public void reconcileBeanConfig()

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());
      }

   }