001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet;
016    
017    import com.liferay.portal.dao.shard.ShardPollerProcessorWrapper;
018    import com.liferay.portal.kernel.atom.AtomCollectionAdapter;
019    import com.liferay.portal.kernel.atom.AtomCollectionAdapterRegistryUtil;
020    import com.liferay.portal.kernel.lar.PortletDataHandler;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.poller.PollerProcessor;
024    import com.liferay.portal.kernel.pop.MessageListener;
025    import com.liferay.portal.kernel.portlet.ConfigurationAction;
026    import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
027    import com.liferay.portal.kernel.portlet.PortletBag;
028    import com.liferay.portal.kernel.portlet.PortletBagPool;
029    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
030    import com.liferay.portal.kernel.portlet.Route;
031    import com.liferay.portal.kernel.portlet.Router;
032    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
033    import com.liferay.portal.kernel.scheduler.SchedulerEntry;
034    import com.liferay.portal.kernel.scheduler.SchedulerException;
035    import com.liferay.portal.kernel.scheduler.StorageType;
036    import com.liferay.portal.kernel.search.Indexer;
037    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
038    import com.liferay.portal.kernel.search.OpenSearch;
039    import com.liferay.portal.kernel.servlet.ServletContextPool;
040    import com.liferay.portal.kernel.servlet.URLEncoder;
041    import com.liferay.portal.kernel.util.GetterUtil;
042    import com.liferay.portal.kernel.util.HttpUtil;
043    import com.liferay.portal.kernel.util.LocaleUtil;
044    import com.liferay.portal.kernel.util.PrefsPropsUtil;
045    import com.liferay.portal.kernel.util.PropsKeys;
046    import com.liferay.portal.kernel.util.PropsUtil;
047    import com.liferay.portal.kernel.util.ProxyFactory;
048    import com.liferay.portal.kernel.util.SetUtil;
049    import com.liferay.portal.kernel.util.StringBundler;
050    import com.liferay.portal.kernel.util.StringPool;
051    import com.liferay.portal.kernel.util.StringUtil;
052    import com.liferay.portal.kernel.util.Validator;
053    import com.liferay.portal.kernel.webdav.WebDAVStorage;
054    import com.liferay.portal.kernel.webdav.WebDAVUtil;
055    import com.liferay.portal.kernel.workflow.WorkflowHandler;
056    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
057    import com.liferay.portal.kernel.xml.Document;
058    import com.liferay.portal.kernel.xml.Element;
059    import com.liferay.portal.kernel.xml.SAXReaderUtil;
060    import com.liferay.portal.kernel.xmlrpc.Method;
061    import com.liferay.portal.language.LanguageResources;
062    import com.liferay.portal.language.LiferayResourceBundle;
063    import com.liferay.portal.model.Portlet;
064    import com.liferay.portal.model.PortletApp;
065    import com.liferay.portal.poller.PollerProcessorUtil;
066    import com.liferay.portal.pop.POPServerUtil;
067    import com.liferay.portal.security.permission.PermissionPropagator;
068    import com.liferay.portal.service.PortletLocalServiceUtil;
069    import com.liferay.portal.util.ClassLoaderUtil;
070    import com.liferay.portal.util.PortalUtil;
071    import com.liferay.portal.util.PropsValues;
072    import com.liferay.portal.xmlrpc.XmlRpcServlet;
073    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
074    import com.liferay.portlet.asset.model.AssetRendererFactory;
075    import com.liferay.portlet.expando.model.CustomAttributesDisplay;
076    import com.liferay.portlet.social.model.SocialActivityInterpreter;
077    import com.liferay.portlet.social.model.SocialRequestInterpreter;
078    import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
079    import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
080    import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
081    import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
082    import com.liferay.util.portlet.PortletProps;
083    
084    import java.io.InputStream;
085    
086    import java.util.ArrayList;
087    import java.util.HashMap;
088    import java.util.List;
089    import java.util.Locale;
090    import java.util.Map;
091    import java.util.ResourceBundle;
092    import java.util.Set;
093    
094    import javax.portlet.PreferencesValidator;
095    
096    import javax.servlet.ServletContext;
097    
098    /**
099     * @author Brian Wing Shun Chan
100     * @author Brian Myunghun Kim
101     * @author Ivica Cardic
102     * @author Raymond Aug??
103     */
104    public class PortletBagFactory {
105    
106            public PortletBag create(Portlet portlet) throws Exception {
107                    PortletApp portletApp = portlet.getPortletApp();
108    
109                    if (!portletApp.isWARFile() && _warFile) {
110                            String contextPath = PortalUtil.getPathContext();
111    
112                            _servletContext = ServletContextPool.get(contextPath);
113    
114                            _classLoader = ClassLoaderUtil.getPortalClassLoader();
115                    }
116    
117                    Class<?> portletClass = null;
118    
119                    try {
120                            portletClass = _classLoader.loadClass(portlet.getPortletClass());
121                    }
122                    catch (Throwable t) {
123                            _log.error(t, t);
124    
125                            PortletLocalServiceUtil.destroyPortlet(portlet);
126    
127                            return null;
128                    }
129    
130                    javax.portlet.Portlet portletInstance =
131                            (javax.portlet.Portlet)portletClass.newInstance();
132    
133                    ConfigurationAction configurationActionInstance =
134                            newConfigurationAction(portlet);
135    
136                    List<Indexer> indexerInstances = newIndexers(portlet);
137    
138                    OpenSearch openSearchInstance = newOpenSearch(portlet);
139    
140                    FriendlyURLMapper friendlyURLMapperInstance = newFriendlyURLMapper(
141                            portlet);
142    
143                    URLEncoder urlEncoderInstance = newURLEncoder(portlet);
144    
145                    PortletDataHandler portletDataHandlerInstance = newPortletDataHandler(
146                            portlet);
147    
148                    PortletLayoutListener portletLayoutListenerInstance =
149                            newPortletLayoutListener(portlet);
150    
151                    PollerProcessor pollerProcessorInstance = newPollerProcessor(portlet);
152    
153                    MessageListener popMessageListenerInstance = newPOPMessageListener(
154                            portlet);
155    
156                    SocialActivityInterpreter socialActivityInterpreterInstance =
157                            initSocialActivityInterpreterInstance(portlet);
158    
159                    SocialRequestInterpreter socialRequestInterpreterInstance = null;
160    
161                    if (Validator.isNotNull(portlet.getSocialRequestInterpreterClass())) {
162                            socialRequestInterpreterInstance =
163                                    (SocialRequestInterpreter)newInstance(
164                                            SocialRequestInterpreter.class,
165                                            portlet.getSocialRequestInterpreterClass());
166    
167                            socialRequestInterpreterInstance = new SocialRequestInterpreterImpl(
168                                    portlet.getPortletId(), socialRequestInterpreterInstance);
169    
170                            SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
171                                    socialRequestInterpreterInstance);
172                    }
173    
174                    WebDAVStorage webDAVStorageInstance = null;
175    
176                    if (Validator.isNotNull(portlet.getWebDAVStorageClass())) {
177                            webDAVStorageInstance = (WebDAVStorage)newInstance(
178                                    WebDAVStorage.class, portlet.getWebDAVStorageClass());
179    
180                            webDAVStorageInstance.setToken(portlet.getWebDAVStorageToken());
181    
182                            WebDAVUtil.addStorage(webDAVStorageInstance);
183                    }
184    
185                    Method xmlRpcMethodInstance = null;
186    
187                    if (Validator.isNotNull(portlet.getXmlRpcMethodClass())) {
188                            xmlRpcMethodInstance = (Method)newInstance(
189                                    Method.class, portlet.getXmlRpcMethodClass());
190    
191                            XmlRpcServlet.registerMethod(xmlRpcMethodInstance);
192                    }
193    
194                    ControlPanelEntry controlPanelEntryInstance = null;
195    
196                    if (Validator.isNotNull(portlet.getControlPanelEntryClass())) {
197                            controlPanelEntryInstance = (ControlPanelEntry)newInstance(
198                                    ControlPanelEntry.class, portlet.getControlPanelEntryClass());
199                    }
200    
201                    List<AssetRendererFactory> assetRendererFactoryInstances =
202                            newAssetRendererFactoryInstances(portlet);
203    
204                    List<AtomCollectionAdapter<?>> atomCollectionAdapterInstances =
205                            newAtomCollectionAdapterInstances(portlet);
206    
207                    List<CustomAttributesDisplay> customAttributesDisplayInstances =
208                            new ArrayList<CustomAttributesDisplay>();
209    
210                    for (String customAttributesDisplayClass :
211                                    portlet.getCustomAttributesDisplayClasses()) {
212    
213                            CustomAttributesDisplay customAttributesDisplayInstance =
214                                    (CustomAttributesDisplay)newInstance(
215                                            CustomAttributesDisplay.class,
216                                            customAttributesDisplayClass);
217    
218                            customAttributesDisplayInstance.setClassNameId(
219                                    PortalUtil.getClassNameId(
220                                            customAttributesDisplayInstance.getClassName()));
221                            customAttributesDisplayInstance.setPortletId(
222                                    portlet.getPortletId());
223    
224                            customAttributesDisplayInstances.add(
225                                    customAttributesDisplayInstance);
226                    }
227    
228                    PermissionPropagator permissionPropagatorInstance =
229                            newPermissionPropagator(portlet);
230    
231                    List<WorkflowHandler> workflowHandlerInstances =
232                            new ArrayList<WorkflowHandler>();
233    
234                    for (String workflowHandlerClass :
235                                    portlet.getWorkflowHandlerClasses()) {
236    
237                            WorkflowHandler workflowHandlerInstance =
238                                    (WorkflowHandler)newInstance(
239                                            WorkflowHandler.class, workflowHandlerClass);
240    
241                            workflowHandlerInstances.add(workflowHandlerInstance);
242    
243                            WorkflowHandlerRegistryUtil.register(workflowHandlerInstance);
244                    }
245    
246                    PreferencesValidator preferencesValidatorInstance = null;
247    
248                    if (Validator.isNotNull(portlet.getPreferencesValidator())) {
249                            preferencesValidatorInstance = (PreferencesValidator)newInstance(
250                                    PreferencesValidator.class, portlet.getPreferencesValidator());
251    
252                            try {
253                                    if (PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
254                                            preferencesValidatorInstance.validate(
255                                                    PortletPreferencesFactoryUtil.fromDefaultXML(
256                                                            portlet.getDefaultPreferences()));
257                                    }
258                            }
259                            catch (Exception e) {
260                                    _log.warn(
261                                            "Portlet with the name " + portlet.getPortletId() +
262                                                    " does not have valid default preferences");
263                            }
264                    }
265    
266                    Map<String, ResourceBundle> resourceBundles = null;
267    
268                    String resourceBundle = portlet.getResourceBundle();
269    
270                    if (Validator.isNotNull(resourceBundle) &&
271                            !resourceBundle.equals(StrutsResourceBundle.class.getName())) {
272    
273                            resourceBundles = new HashMap<String, ResourceBundle>();
274    
275                            initResourceBundle(resourceBundles, portlet, null);
276                            initResourceBundle(
277                                    resourceBundles, portlet, LocaleUtil.getDefault());
278    
279                            Set<String> supportedLocales = portlet.getSupportedLocales();
280    
281                            if (supportedLocales.isEmpty()) {
282                                    supportedLocales = SetUtil.fromArray(PropsValues.LOCALES);
283                            }
284    
285                            for (String supportedLocale : supportedLocales) {
286                                    Locale locale = LocaleUtil.fromLanguageId(supportedLocale);
287    
288                                    initResourceBundle(resourceBundles, portlet, locale);
289                            }
290                    }
291    
292                    PortletBag portletBag = new PortletBagImpl(
293                            portlet.getPortletId(), _servletContext, portletInstance,
294                            configurationActionInstance, indexerInstances, openSearchInstance,
295                            friendlyURLMapperInstance, urlEncoderInstance,
296                            portletDataHandlerInstance, portletLayoutListenerInstance,
297                            pollerProcessorInstance, popMessageListenerInstance,
298                            socialActivityInterpreterInstance, socialRequestInterpreterInstance,
299                            webDAVStorageInstance, xmlRpcMethodInstance,
300                            controlPanelEntryInstance, assetRendererFactoryInstances,
301                            atomCollectionAdapterInstances, customAttributesDisplayInstances,
302                            permissionPropagatorInstance, workflowHandlerInstances,
303                            preferencesValidatorInstance, resourceBundles);
304    
305                    PortletBagPool.put(portlet.getRootPortletId(), portletBag);
306    
307                    initSchedulers(portlet);
308    
309                    try {
310                            PortletInstanceFactoryUtil.create(portlet, _servletContext);
311                    }
312                    catch (Exception e) {
313                            _log.error(e, e);
314                    }
315    
316                    return portletBag;
317            }
318    
319            public void setClassLoader(ClassLoader classLoader) {
320                    _classLoader = classLoader;
321            }
322    
323            public void setServletContext(ServletContext servletContext) {
324                    _servletContext = servletContext;
325            }
326    
327            public void setWARFile(boolean warFile) {
328                    _warFile = warFile;
329            }
330    
331            protected String getContent(String fileName) throws Exception {
332                    String queryString = HttpUtil.getQueryString(fileName);
333    
334                    if (Validator.isNull(queryString)) {
335                            return StringUtil.read(_classLoader, fileName);
336                    }
337    
338                    int pos = fileName.indexOf(StringPool.QUESTION);
339    
340                    String xml = StringUtil.read(_classLoader, fileName.substring(0, pos));
341    
342                    Map<String, String[]> parameterMap = HttpUtil.getParameterMap(
343                            queryString);
344    
345                    if (parameterMap == null) {
346                            return xml;
347                    }
348    
349                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
350                            String name = entry.getKey();
351                            String[] values = entry.getValue();
352    
353                            if (values.length == 0) {
354                                    continue;
355                            }
356    
357                            String value = values[0];
358    
359                            xml = StringUtil.replace(xml, "@" + name + "@", value);
360                    }
361    
362                    return xml;
363            }
364    
365            protected String getPluginPropertyValue(String propertyKey)
366                    throws Exception {
367    
368                    Class<?> clazz = _classLoader.loadClass(PortletProps.class.getName());
369    
370                    java.lang.reflect.Method method = clazz.getMethod("get", String.class);
371    
372                    return (String)method.invoke(null, propertyKey);
373            }
374    
375            protected InputStream getResourceBundleInputStream(
376                    String resourceBundleName, Locale locale) {
377    
378                    resourceBundleName = resourceBundleName.replace(
379                            StringPool.PERIOD, StringPool.SLASH);
380    
381                    Locale newLocale = locale;
382    
383                    InputStream inputStream = null;
384    
385                    while (inputStream == null) {
386                            locale = newLocale;
387    
388                            StringBundler sb = new StringBundler(4);
389    
390                            sb.append(resourceBundleName);
391    
392                            if (locale != null) {
393                                    String localeName = locale.toString();
394    
395                                    if (localeName.length() > 0) {
396                                            sb.append(StringPool.UNDERLINE);
397                                            sb.append(localeName);
398                                    }
399                            }
400    
401                            if (!resourceBundleName.endsWith(".properties")) {
402                                    sb.append(".properties");
403                            }
404    
405                            String localizedResourceBundleName = sb.toString();
406    
407                            if (_log.isInfoEnabled()) {
408                                    _log.info("Attempting to load " + localizedResourceBundleName);
409                            }
410    
411                            inputStream = _classLoader.getResourceAsStream(
412                                    localizedResourceBundleName);
413    
414                            if (locale == null) {
415                                    break;
416                            }
417    
418                            newLocale = LanguageResources.getSuperLocale(locale);
419    
420                            if (newLocale == null) {
421                                    break;
422                            }
423    
424                            if (newLocale.equals(locale)) {
425                                    break;
426                            }
427                    }
428    
429                    return inputStream;
430            }
431    
432            protected void initResourceBundle(
433                    Map<String, ResourceBundle> resourceBundles, Portlet portlet,
434                    Locale locale) {
435    
436                    try {
437                            InputStream inputStream = getResourceBundleInputStream(
438                                    portlet.getResourceBundle(), locale);
439    
440                            if (inputStream != null) {
441                                    ResourceBundle parentResourceBundle = null;
442    
443                                    if (locale != null) {
444                                            parentResourceBundle = resourceBundles.get(null);
445                                    }
446    
447                                    ResourceBundle resourceBundle = new LiferayResourceBundle(
448                                            parentResourceBundle, inputStream, StringPool.UTF8);
449    
450                                    String languageId = null;
451    
452                                    if (locale != null) {
453                                            languageId = LocaleUtil.toLanguageId(locale);
454                                    }
455    
456                                    resourceBundles.put(languageId, resourceBundle);
457                            }
458                    }
459                    catch (Exception e) {
460                            _log.warn(e.getMessage());
461                    }
462            }
463    
464            protected void initScheduler(
465                            SchedulerEntry schedulerEntry, String portletId)
466                    throws Exception {
467    
468                    String propertyKey = schedulerEntry.getPropertyKey();
469    
470                    if (Validator.isNotNull(propertyKey)) {
471                            String triggerValue = null;
472    
473                            if (_warFile) {
474                                    triggerValue = getPluginPropertyValue(propertyKey);
475                            }
476                            else {
477                                    triggerValue = PrefsPropsUtil.getString(propertyKey);
478                            }
479    
480                            if (_log.isDebugEnabled()) {
481                                    _log.debug(
482                                            "Scheduler property key " + propertyKey +
483                                                    " has trigger value " + triggerValue);
484                            }
485    
486                            if (Validator.isNull(triggerValue)) {
487                                    throw new SchedulerException(
488                                            "Property key " + propertyKey + " requires a value");
489                            }
490    
491                            schedulerEntry.setTriggerValue(triggerValue);
492                    }
493    
494                    if (_classLoader == ClassLoaderUtil.getPortalClassLoader()) {
495                            portletId = null;
496                    }
497    
498                    SchedulerEngineHelperUtil.schedule(
499                            schedulerEntry, StorageType.MEMORY_CLUSTERED, portletId, 0);
500            }
501    
502            protected void initSchedulers(Portlet portlet) throws Exception {
503                    if (!PropsValues.SCHEDULER_ENABLED) {
504                            return;
505                    }
506    
507                    List<SchedulerEntry> schedulerEntries = portlet.getSchedulerEntries();
508    
509                    if ((schedulerEntries == null) || schedulerEntries.isEmpty()) {
510                            return;
511                    }
512    
513                    for (SchedulerEntry schedulerEntry : schedulerEntries) {
514                            initScheduler(schedulerEntry, portlet.getPortletId());
515                    }
516            }
517    
518            protected SocialActivityInterpreter initSocialActivityInterpreterInstance(
519                            Portlet portlet)
520                    throws Exception {
521    
522                    if (Validator.isNull(portlet.getSocialActivityInterpreterClass())) {
523                            return null;
524                    }
525    
526                    SocialActivityInterpreter socialActivityInterpreterInstance =
527                            (SocialActivityInterpreter)newInstance(
528                                    SocialActivityInterpreter.class,
529                                    portlet.getSocialActivityInterpreterClass());
530    
531                    socialActivityInterpreterInstance =
532                            new SocialActivityInterpreterImpl(
533                                    portlet.getPortletId(), socialActivityInterpreterInstance);
534    
535                    SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
536                            socialActivityInterpreterInstance);
537    
538                    return socialActivityInterpreterInstance;
539            }
540    
541            protected AssetRendererFactory newAssetRendererFactoryInstance(
542                            Portlet portlet, String assetRendererFactoryClass)
543                    throws Exception {
544    
545                    AssetRendererFactory assetRendererFactoryInstance =
546                            (AssetRendererFactory)newInstance(
547                                    AssetRendererFactory.class, assetRendererFactoryClass);
548    
549                    assetRendererFactoryInstance.setClassName(
550                            assetRendererFactoryInstance.getClassName());
551                    assetRendererFactoryInstance.setPortletId(portlet.getPortletId());
552    
553                    AssetRendererFactoryRegistryUtil.register(assetRendererFactoryInstance);
554    
555                    return assetRendererFactoryInstance;
556            }
557    
558            protected List<AssetRendererFactory> newAssetRendererFactoryInstances(
559                            Portlet portlet)
560                    throws Exception {
561    
562                    List<AssetRendererFactory> assetRendererFactoryInstances =
563                            new ArrayList<AssetRendererFactory>();
564    
565                    for (String assetRendererFactoryClass :
566                                    portlet.getAssetRendererFactoryClasses()) {
567    
568                            String assetRendererEnabledPropertyKey =
569                                    PropsKeys.ASSET_RENDERER_ENABLED + assetRendererFactoryClass;
570    
571                            String assetRendererEnabledPropertyValue = null;
572    
573                            if (_warFile) {
574                                    assetRendererEnabledPropertyValue = getPluginPropertyValue(
575                                            assetRendererEnabledPropertyKey);
576                            }
577                            else {
578                                    assetRendererEnabledPropertyValue = PropsUtil.get(
579                                            assetRendererEnabledPropertyKey);
580                            }
581    
582                            boolean assetRendererEnabledValue = GetterUtil.getBoolean(
583                                    assetRendererEnabledPropertyValue, true);
584    
585                            if (assetRendererEnabledValue) {
586                                    AssetRendererFactory assetRendererFactoryInstance =
587                                            newAssetRendererFactoryInstance(
588                                                    portlet, assetRendererFactoryClass);
589    
590                                    assetRendererFactoryInstances.add(assetRendererFactoryInstance);
591                            }
592                    }
593    
594                    return assetRendererFactoryInstances;
595            }
596    
597            protected List<AtomCollectionAdapter<?>> newAtomCollectionAdapterInstances(
598                            Portlet portlet)
599                    throws Exception {
600    
601                    List<AtomCollectionAdapter<?>> atomCollectionAdapterInstances =
602                            new ArrayList<AtomCollectionAdapter<?>>();
603    
604                    for (String atomCollectionAdapterClass :
605                                    portlet.getAtomCollectionAdapterClasses()) {
606    
607                            AtomCollectionAdapter<?> atomCollectionAdapterInstance =
608                                    (AtomCollectionAdapter<?>)newInstance(
609                                            AtomCollectionAdapter.class, atomCollectionAdapterClass);
610    
611                            AtomCollectionAdapterRegistryUtil.register(
612                                    atomCollectionAdapterInstance);
613    
614                            atomCollectionAdapterInstances.add(atomCollectionAdapterInstance);
615                    }
616    
617                    return atomCollectionAdapterInstances;
618            }
619    
620            protected ConfigurationAction newConfigurationAction(Portlet portlet)
621                    throws Exception {
622    
623                    if (Validator.isNull(portlet.getConfigurationActionClass())) {
624                            return null;
625                    }
626    
627                    return (ConfigurationAction)newInstance(
628                            ConfigurationAction.class, portlet.getConfigurationActionClass());
629            }
630    
631            protected FriendlyURLMapper newFriendlyURLMapper(Portlet portlet)
632                    throws Exception {
633    
634                    if (Validator.isNull(portlet.getFriendlyURLMapperClass())) {
635                            return null;
636                    }
637    
638                    FriendlyURLMapper friendlyURLMapper = (FriendlyURLMapper)newInstance(
639                            FriendlyURLMapper.class, portlet.getFriendlyURLMapperClass());
640    
641                    friendlyURLMapper.setMapping(portlet.getFriendlyURLMapping());
642                    friendlyURLMapper.setPortletId(portlet.getPortletId());
643                    friendlyURLMapper.setPortletInstanceable(portlet.isInstanceable());
644    
645                    Router router = newFriendlyURLRouter(portlet);
646    
647                    friendlyURLMapper.setRouter(router);
648    
649                    return friendlyURLMapper;
650            }
651    
652            protected Router newFriendlyURLRouter(Portlet portlet) throws Exception {
653                    if (Validator.isNull(portlet.getFriendlyURLRoutes())) {
654                            return null;
655                    }
656    
657                    Router router = new RouterImpl();
658    
659                    String xml = getContent(portlet.getFriendlyURLRoutes());
660    
661                    Document document = SAXReaderUtil.read(xml, true);
662    
663                    Element rootElement = document.getRootElement();
664    
665                    for (Element routeElement : rootElement.elements("route")) {
666                            String pattern = routeElement.elementText("pattern");
667    
668                            Route route = router.addRoute(pattern);
669    
670                            for (Element generatedParameterElement :
671                                            routeElement.elements("generated-parameter")) {
672    
673                                    String name = generatedParameterElement.attributeValue("name");
674                                    String value = generatedParameterElement.getText();
675    
676                                    route.addGeneratedParameter(name, value);
677                            }
678    
679                            for (Element ignoredParameterElement :
680                                            routeElement.elements("ignored-parameter")) {
681    
682                                    String name = ignoredParameterElement.attributeValue("name");
683    
684                                    route.addIgnoredParameter(name);
685                            }
686    
687                            for (Element implicitParameterElement :
688                                            routeElement.elements("implicit-parameter")) {
689    
690                                    String name = implicitParameterElement.attributeValue("name");
691                                    String value = implicitParameterElement.getText();
692    
693                                    route.addImplicitParameter(name, value);
694                            }
695    
696                            for (Element overriddenParameterElement :
697                                            routeElement.elements("overridden-parameter")) {
698    
699                                    String name = overriddenParameterElement.attributeValue("name");
700                                    String value = overriddenParameterElement.getText();
701    
702                                    route.addOverriddenParameter(name, value);
703                            }
704                    }
705    
706                    return router;
707            }
708    
709            protected List<Indexer> newIndexers(Portlet portlet) throws Exception {
710                    List<Indexer> indexerInstances = new ArrayList<Indexer>();
711    
712                    List<String> indexerClasses = portlet.getIndexerClasses();
713    
714                    for (String indexerClass : indexerClasses) {
715                            Indexer indexerInstance = (Indexer)newInstance(
716                                    Indexer.class, indexerClass);
717    
718                            IndexerRegistryUtil.register(indexerInstance);
719    
720                            indexerInstances.add(indexerInstance);
721                    }
722    
723                    return indexerInstances;
724            }
725    
726            protected Object newInstance(Class<?> interfaceClass, String implClassName)
727                    throws Exception {
728    
729                    return newInstance(new Class[] {interfaceClass}, implClassName);
730            }
731    
732            protected Object newInstance(
733                            Class<?>[] interfaceClasses, String implClassName)
734                    throws Exception {
735    
736                    if (_warFile) {
737                            return ProxyFactory.newInstance(
738                                    _classLoader, interfaceClasses, implClassName);
739                    }
740                    else {
741                            Class<?> clazz = _classLoader.loadClass(implClassName);
742    
743                            return clazz.newInstance();
744                    }
745            }
746    
747            protected OpenSearch newOpenSearch(Portlet portlet) throws Exception {
748                    if (Validator.isNull(portlet.getOpenSearchClass())) {
749                            return null;
750                    }
751    
752                    return (OpenSearch)newInstance(
753                            OpenSearch.class, portlet.getOpenSearchClass());
754            }
755    
756            protected PermissionPropagator newPermissionPropagator(Portlet portlet)
757                    throws Exception {
758    
759                    if (Validator.isNull(portlet.getPermissionPropagatorClass())) {
760                            return null;
761                    }
762    
763                    return (PermissionPropagator)newInstance(
764                            PermissionPropagator.class, portlet.getPermissionPropagatorClass());
765            }
766    
767            protected PollerProcessor newPollerProcessor(Portlet portlet)
768                    throws Exception {
769    
770                    if (Validator.isNull(portlet.getPollerProcessorClass())) {
771                            return null;
772                    }
773    
774                    PollerProcessor pollerProcessorInstance = (PollerProcessor)newInstance(
775                            PollerProcessor.class, portlet.getPollerProcessorClass());
776    
777                    PollerProcessorUtil.addPollerProcessor(
778                            portlet.getPortletId(),
779                            new ShardPollerProcessorWrapper(pollerProcessorInstance));
780    
781                    return pollerProcessorInstance;
782            }
783    
784            protected MessageListener newPOPMessageListener(Portlet portlet)
785                    throws Exception {
786    
787                    if (Validator.isNull(portlet.getPopMessageListenerClass())) {
788                            return null;
789                    }
790    
791                    MessageListener popMessageListenerInstance =
792                            (MessageListener)newInstance(
793                                    MessageListener.class, portlet.getPopMessageListenerClass());
794    
795                    POPServerUtil.addListener(popMessageListenerInstance);
796    
797                    return popMessageListenerInstance;
798            }
799    
800            protected PortletDataHandler newPortletDataHandler(Portlet portlet)
801                    throws Exception {
802    
803                    if (Validator.isNull(portlet.getPortletDataHandlerClass())) {
804                            return null;
805                    }
806    
807                    return (PortletDataHandler)newInstance(
808                            PortletDataHandler.class, portlet.getPortletDataHandlerClass());
809            }
810    
811            protected PortletLayoutListener newPortletLayoutListener(Portlet portlet)
812                    throws Exception {
813    
814                    if (Validator.isNull(portlet.getPortletLayoutListenerClass())) {
815                            return null;
816                    }
817    
818                    return (PortletLayoutListener)newInstance(
819                            PortletLayoutListener.class,
820                            portlet.getPortletLayoutListenerClass());
821            }
822    
823            protected URLEncoder newURLEncoder(Portlet portlet) throws Exception {
824                    if (Validator.isNull(portlet.getURLEncoderClass())) {
825                            return null;
826                    }
827    
828                    return (URLEncoder)newInstance(
829                            URLEncoder.class, portlet.getURLEncoderClass());
830            }
831    
832            private static Log _log = LogFactoryUtil.getLog(PortletBagFactory.class);
833    
834            private ClassLoader _classLoader;
835            private ServletContext _servletContext;
836            private boolean _warFile;
837    
838    }