in pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java [408:719]
public void reconcileBeanConfig(AnnotatedMethodStore ams) {
Set<String> portletNames = ams.getPortletNames();
// the wildcard is only in the store for display / debug purposes. don't reconcile.
portletNames.remove("*");
if (isDebug) {
StringBuilder txt = new StringBuilder();
txt.append("Beginning reconciliation. Annotated portlets: ").append(portletNames.toString());
LOG.debug(txt.toString());
}
ams.setDefaultNamespace(pad.getDefaultNamespace());
for (String pn : portletNames) {
// copy data from the method store to the portlet definition
PortletDefinition pd = pad.getPortlet(pn);
if (pd == null) {
// Implied configuration; no portlet.xml or @PortletConfiguration data
pd = new PortletDefinitionImpl(pn, pad);
}
if (pd.getSupports().isEmpty()) {
// add default and implicitly configured values
// there can potentially be multiple mime types configured
Map<String, Supports> mimeSupps = new HashMap<String, Supports>();
Set<MethodIdentifier> mis = ams.getMethodIDsForPortlet(pn);
for (MethodIdentifier mi : mis) {
if (mi.getType() == MethodType.RENDER) {
String mode = (String) mi.getId();
if (mode.equalsIgnoreCase("view") || mode.equalsIgnoreCase("help") || mode.equalsIgnoreCase("edit")) {
List<AnnotatedMethod> meths = ams.getMethods(mi);
for (AnnotatedMethod meth : meths) {
RenderMethod rm = (RenderMethod) meth.getAnnotation();
String mimeType = "*/*";
if (rm != null) {
mimeType = rm.contentType().replaceAll(" ", "").replaceAll("([^;]+).*", "$1").toLowerCase();
mimeType = mimeType.equals("*") ? "*/*" : mimeType;
}
Supports sup = mimeSupps.get(mimeType);
if (sup == null) {
sup = new SupportsImpl(mimeType);
mimeSupps.put(mimeType, sup);
}
if (!sup.getPortletModes().contains(mode)) {
sup.addPortletMode(mode);
}
}
}
}
}
for (Supports sup : mimeSupps.values()) {
pd.addSupports(sup);
}
if (isDebug) {
StringBuilder txt = new StringBuilder();
txt.append("There are ").append(mimeSupps.size()).append(" unique MIME types configured:");
for (String mt : mimeSupps.keySet()) {
txt.append("\n MIME: ").append(mt);
txt.append(", portlet modes: ");
txt.append(((Supports)mimeSupps.get(mt)).getPortletModes().toString());
}
LOG.debug(txt.toString());
}
}
// if one of the @serveResourceMethod annotations has its ayncSupported
// flag set to true, set the flag to true in the portlet definition
Set<MethodIdentifier> mis = ams.getMethodIDsForPortlet(pn);
for (MethodIdentifier mi : mis) {
if (mi.getType() == MethodType.RESOURCE) {
List<AnnotatedMethod> meths = ams.getMethods(mi);
for (AnnotatedMethod meth : meths) {
ServeResourceMethod srm = (ServeResourceMethod) meth.getAnnotation();
if (srm != null && srm.asyncSupported()) {
pd.setAsyncSupported(true);
}
}
}
}
// The processing event references
List<EventDefinitionReference> edrs = pd.getSupportedProcessingEvents();
for (QName qn : ams.getProcessingEventRefs(pn)) {
EventDefinition ed = pad.getEventDefinition(qn);
if (ed == null) {
StringBuilder txt = new StringBuilder(128);
txt.append("No event definition found for annotated processing event reference.");
txt.append(" Portlet name: ").append(pn);
txt.append(", QName: ").append(qn);
LOG.warn(txt.toString());
// remove the defective method from the store
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), qn, MethodType.EVENT);
ams.removeMethod(mi);
continue;
}
EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
if (!edrs.contains(newedr)) {
pd.addSupportedProcessingEvent(newedr);
}
}
// The publishing event references
edrs = pd.getSupportedPublishingEvents();
for (QName qn : ams.getPublishingEventRefs(pn)) {
EventDefinition ed = pad.getEventDefinition(qn);
if (ed == null) {
StringBuilder txt = new StringBuilder(128);
txt.append("No event definition found for annotated publishing event reference.");
txt.append(" Portlet name: ").append(pn);
txt.append(", QName: ").append(qn);
LOG.warn(txt.toString());
continue;
}
EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
if (!edrs.contains(newedr)) {
pd.addSupportedPublishingEvent(newedr);
}
}
pad.addPortlet(pd);
}
// Now add the declared portlet class methods to the store
for (PortletDefinition pd : pad.getPortlets()) {
Class<?> cls = null;
String clsName = pd.getPortletClass();
if (isValidIdentifier(clsName)) {
// Make sure the class can be loaded
Class<?> valClass = null;
StringBuilder txt = new StringBuilder(128);
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = this.getClass().getClassLoader();
}
valClass = cl.loadClass(clsName);
if (Portlet.class.isAssignableFrom(valClass)) {
cls = valClass;
} else {
txt.append("Specified portlet class does not implement the Portlet interface.");
}
} catch (Exception e) {
txt.append("Specified portlet class could not be loaded.");
} finally {
if (cls == null) {
txt.append(" Portlet name: ").append(pd.getPortletName());
txt.append(", Portlet class: ").append(clsName);
LOG.warn(txt.toString());
}
}
}
if (cls != null) {
// extract the methods from the portlet class and add them to the method store
// as long there is no corresponding annotated method already present.
// (annotated methods take precedence over portlet class methods).
AnnotatedMethod am;
am = getMethod(cls, "init", METH_INI);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.INIT);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "destroy", METH_DES);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.DESTROY);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "processAction", METH_ACT);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.ACTION);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "processEvent", METH_EVT);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.EVENT);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "render", METH_REN);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RENDER);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "renderHeaders", METH_HDR);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.HEADER);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
am = getMethod(cls, "serveResource", METH_RES);
if (am != null) {
MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RESOURCE);
if (ams.getMethods(mi).size() == 0) {
ams.addMethod(mi, am);
}
}
}
}
// At this point we have all portlet methods in the store.
// See if there is a portlet with a wild-card character. If so, then
// replicate the method identifiers to cover all other portlet names
Set<MethodIdentifier> mis = ams.getMethodIDsForPortlet("*");
if (isDebug) {
StringBuilder txt = new StringBuilder();
txt.append("Wild card portlets: ");
String sep = "";
for (MethodIdentifier mi : mis) {
txt.append(sep).append(mi.toString());
sep = ";";
}
LOG.debug(txt.toString());
}
for (MethodIdentifier mi : mis) {
List<AnnotatedMethod> meths = ams.getMethods(mi);
for (PortletDefinition pd : pad.getPortlets()) {
MethodIdentifier newMi = new MethodIdentifier(pd.getPortletName(), mi.getId(), mi.getType());
for (AnnotatedMethod meth : meths) {
ams.addMethod(newMi, meth);
}
}
}
// and finally make sure that each portlet has at least one render, header, or serveResource
// method. If not, delete it.
List<PortletDefinition> badPortlets = new ArrayList<PortletDefinition>();
for (PortletDefinition pd : pad.getPortlets()) {
boolean methodsOK = false;
for (MethodIdentifier mi : ams.getMethodIDsForPortlet(pd.getPortletName())) {
if ((mi.getType() == MethodType.RENDER) || (mi.getType() == MethodType.RESOURCE) || (mi.getType() == MethodType.HEADER)) {
methodsOK = true;
break;
}
}
if (!methodsOK) {
ams.removeMethodsForPortlet(pd.getPortletName());
badPortlets.add(pd);
StringBuilder txt = new StringBuilder();
txt.append("Portlet does not have a render, resource, or header method, so cannot be taken into service. ");
txt.append("Portlet name: ").append(pd.getPortletName());
LOG.warn(txt.toString());
}
}
// if there are bad portlets, delete them from the config
for (PortletDefinition pd : badPortlets) {
pad.removePortlet(pd);
}
if (isDebug) {
StringBuilder txt = new StringBuilder();
txt.append("Finished reconciling bean config. ");
Set<String> finalNames = ams.getPortletNames();
finalNames.remove("*"); // don't display wildcard
txt.append("Resulting portlet list: ").append(finalNames.toString());
LOG.debug(txt.toString());
}
if (isTrace) {
StringBuilder txt = new StringBuilder();
txt.append(ams.getMethodsAsString());
LOG.trace(txt.toString());
}
}