1
22
23 package com.liferay.portal.service.impl;
24
25 import com.liferay.portal.SystemException;
26 import com.liferay.portal.kernel.plugin.PluginPackage;
27 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.ListUtil;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.Validator;
32 import com.liferay.portal.kernel.xml.Document;
33 import com.liferay.portal.kernel.xml.Element;
34 import com.liferay.portal.kernel.xml.SAXReaderUtil;
35 import com.liferay.portal.model.CompanyConstants;
36 import com.liferay.portal.model.EventDefinition;
37 import com.liferay.portal.model.Portlet;
38 import com.liferay.portal.model.PortletApp;
39 import com.liferay.portal.model.PortletCategory;
40 import com.liferay.portal.model.PortletConstants;
41 import com.liferay.portal.model.PortletFilter;
42 import com.liferay.portal.model.PortletInfo;
43 import com.liferay.portal.model.PortletURLListener;
44 import com.liferay.portal.model.PublicRenderParameter;
45 import com.liferay.portal.model.impl.EventDefinitionImpl;
46 import com.liferay.portal.model.impl.PortletAppImpl;
47 import com.liferay.portal.model.impl.PortletFilterImpl;
48 import com.liferay.portal.model.impl.PortletImpl;
49 import com.liferay.portal.model.impl.PortletURLListenerImpl;
50 import com.liferay.portal.model.impl.PublicRenderParameterImpl;
51 import com.liferay.portal.service.base.PortletLocalServiceBaseImpl;
52 import com.liferay.portal.util.ContentUtil;
53 import com.liferay.portal.util.PortalUtil;
54 import com.liferay.portal.util.PortletKeys;
55 import com.liferay.portal.util.PropsValues;
56 import com.liferay.portal.util.QNameUtil;
57 import com.liferay.portlet.PortletPreferencesSerializer;
58
59 import java.util.ArrayList;
60 import java.util.HashMap;
61 import java.util.HashSet;
62 import java.util.Iterator;
63 import java.util.LinkedHashSet;
64 import java.util.List;
65 import java.util.Map;
66 import java.util.Set;
67 import java.util.concurrent.ConcurrentHashMap;
68
69 import javax.portlet.PortletMode;
70 import javax.portlet.PreferencesValidator;
71
72 import javax.xml.namespace.QName;
73
74 import org.apache.commons.logging.Log;
75 import org.apache.commons.logging.LogFactory;
76
77
84 public class PortletLocalServiceImpl extends PortletLocalServiceBaseImpl {
85
86 public void destroyPortlet(Portlet portlet) {
87 Map<String, Portlet> portletsPool = _getPortletsPool();
88
89 portletsPool.remove(portlet.getRootPortletId());
90
91 PortletApp portletApp = portlet.getPortletApp();
92
93 _portletAppsPool.remove(portletApp.getServletContextName());
94
95 _clearCaches();
96 }
97
98 public PortletCategory getEARDisplay(String xml) throws SystemException {
99 try {
100 return _readLiferayDisplayXML(xml);
101 }
102 catch (Exception e) {
103 throw new SystemException(e);
104 }
105 }
106
107 public PortletCategory getWARDisplay(String servletContextName, String xml)
108 throws SystemException {
109
110 try {
111 return _readLiferayDisplayXML(servletContextName, xml);
112 }
113 catch (Exception e) {
114 throw new SystemException(e);
115 }
116 }
117
118 public List<FriendlyURLMapper> getFriendlyURLMappers() {
119 return _getFriendlyURLMappers();
120 }
121
122 public Portlet getPortletById(long companyId, String portletId)
123 throws SystemException {
124
125 portletId = PortalUtil.getJsSafePortletId(portletId);
126
127 Portlet portlet = null;
128
129 Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
130
131 String rootPortletId = PortletConstants.getRootPortletId(portletId);
132
133 if (portletId.equals(rootPortletId)) {
134 portlet = companyPortletsPool.get(portletId);
135 }
136 else {
137 portlet = companyPortletsPool.get(rootPortletId);
138
139 if (portlet != null) {
140 portlet = portlet.getClonedInstance(portletId);
141 }
142 }
143
144 if ((portlet == null) &&
145 (!portletId.equals(PortletKeys.LIFERAY_PORTAL))) {
146
147 if (_portletsPool.isEmpty()) {
148 if (_log.isDebugEnabled()) {
149 _log.debug("No portlets are installed");
150 }
151 }
152 else {
153 if (_log.isWarnEnabled()) {
154 _log.warn(
155 "Portlet not found for " + companyId + " " + portletId);
156 }
157 }
158 }
159
160 return portlet;
161 }
162
163 public Portlet getPortletByStrutsPath(long companyId, String strutsPath)
164 throws SystemException {
165
166 return getPortletById(companyId, _getPortletId(strutsPath));
167 }
168
169 public List<Portlet> getPortlets() {
170 Map<String, Portlet> portletsPool = _getPortletsPool();
171
172 return ListUtil.fromCollection(portletsPool.values());
173 }
174
175 public List<Portlet> getPortlets(long companyId) throws SystemException {
176 return getPortlets(companyId, true, true);
177 }
178
179 public List<Portlet> getPortlets(
180 long companyId, boolean showSystem, boolean showPortal)
181 throws SystemException {
182
183 Map<String, Portlet> portletsPool = _getPortletsPool(companyId);
184
185 List<Portlet> portlets = ListUtil.fromCollection(portletsPool.values());
186
187 if (!showSystem || !showPortal) {
188 Iterator<Portlet> itr = portlets.iterator();
189
190 while (itr.hasNext()) {
191 Portlet portlet = itr.next();
192
193 if (showPortal &&
194 portlet.getPortletId().equals(PortletKeys.PORTAL)) {
195
196 }
197 else if (!showPortal &&
198 portlet.getPortletId().equals(PortletKeys.PORTAL)) {
199
200 itr.remove();
201 }
202 else if (!showSystem && portlet.isSystem()) {
203 itr.remove();
204 }
205 }
206 }
207
208 return portlets;
209 }
210
211 public boolean hasPortlet(long companyId, String portletId)
212 throws SystemException {
213
214 portletId = PortalUtil.getJsSafePortletId(portletId);
215
216 Portlet portlet = null;
217
218 Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
219
220 String rootPortletId = PortletConstants.getRootPortletId(portletId);
221
222 if (portletId.equals(rootPortletId)) {
223 portlet = companyPortletsPool.get(portletId);
224 }
225 else {
226 portlet = companyPortletsPool.get(rootPortletId);
227 }
228
229 if (portlet == null) {
230 return false;
231 }
232 else {
233 return true;
234 }
235 }
236
237 public void initEAR(String[] xmls, PluginPackage pluginPackage) {
238
239
241 _portletAppsPool.clear();
242 _portletsPool.clear();
243 _companyPortletsPool.clear();
244 _portletIdsByStrutsPath.clear();
245 _friendlyURLMapperPortlets.clear();
246
247 Map<String, Portlet> portletsPool = _getPortletsPool();
248
249 try {
250 List<String> servletURLPatterns = _readWebXML(xmls[4]);
251
252 Set<String> portletIds = _readPortletXML(
253 xmls[0], portletsPool, servletURLPatterns, pluginPackage);
254
255 portletIds.addAll(_readPortletXML(
256 xmls[1], portletsPool, servletURLPatterns, pluginPackage));
257
258 Set<String> liferayPortletIds =
259 _readLiferayPortletXML(xmls[2], portletsPool);
260
261 liferayPortletIds.addAll(
262 _readLiferayPortletXML(xmls[3], portletsPool));
263
264
266 Iterator<String> portletIdsItr = portletIds.iterator();
267
268 while (portletIdsItr.hasNext()) {
269 String portletId = portletIdsItr.next();
270
271 if (_log.isWarnEnabled() &&
272 !liferayPortletIds.contains(portletId)) {
273
274 _log.warn(
275 "Portlet with the name " + portletId +
276 " is described in portlet.xml but does not " +
277 "have a matching entry in liferay-portlet.xml");
278 }
279 }
280
281
283 Iterator<String> liferayPortletIdsItr =
284 liferayPortletIds.iterator();
285
286 while (liferayPortletIdsItr.hasNext()) {
287 String portletId = liferayPortletIdsItr.next();
288
289 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
290 _log.warn(
291 "Portlet with the name " + portletId +
292 " is described in liferay-portlet.xml but does " +
293 "not have a matching entry in portlet.xml");
294 }
295 }
296
297
299 Iterator<Map.Entry<String, Portlet>> portletPoolsItr =
300 portletsPool.entrySet().iterator();
301
302 while (portletPoolsItr.hasNext()) {
303 Map.Entry<String, Portlet> entry = portletPoolsItr.next();
304
305 Portlet portletModel = entry.getValue();
306
307 if (!portletModel.getPortletId().equals(PortletKeys.ADMIN) &&
308 !portletModel.getPortletId().equals(
309 PortletKeys.MY_ACCOUNT) &&
310 !portletModel.isInclude()) {
311
312 portletPoolsItr.remove();
313 }
314 }
315 }
316 catch (Exception e) {
317 _log.error(e, e);
318 }
319 }
320
321 public List<Portlet> initWAR(
322 String servletContextName, String[] xmls, PluginPackage pluginPackage) {
323
324 List<Portlet> portlets = new ArrayList<Portlet>();
325
326 Map<String, Portlet> portletsPool = _getPortletsPool();
327
328 try {
329 List<String> servletURLPatterns = _readWebXML(xmls[3]);
330
331 Set<String> portletIds = _readPortletXML(
332 servletContextName, xmls[0], portletsPool, servletURLPatterns,
333 pluginPackage);
334
335 portletIds.addAll(_readPortletXML(
336 servletContextName, xmls[1], portletsPool, servletURLPatterns,
337 pluginPackage));
338
339 Set<String> liferayPortletIds = _readLiferayPortletXML(
340 servletContextName, xmls[2], portletsPool);
341
342
344 Iterator<String> itr = portletIds.iterator();
345
346 while (itr.hasNext()) {
347 String portletId = itr.next();
348
349 if (_log.isWarnEnabled() &&
350 !liferayPortletIds.contains(portletId)) {
351
352 _log.warn(
353 "Portlet with the name " + portletId +
354 " is described in portlet.xml but does not " +
355 "have a matching entry in liferay-portlet.xml");
356 }
357 }
358
359
361 itr = liferayPortletIds.iterator();
362
363 while (itr.hasNext()) {
364 String portletId = itr.next();
365
366 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
367 _log.warn(
368 "Portlet with the name " + portletId +
369 " is described in liferay-portlet.xml but does " +
370 "not have a matching entry in portlet.xml");
371 }
372 }
373
374
376 itr = portletIds.iterator();
377
378 while (itr.hasNext()) {
379 String portletId = itr.next();
380
381 Portlet portlet = _getPortletsPool().get(portletId);
382
383 portlets.add(portlet);
384 }
385 }
386 catch (Exception e) {
387 _log.error(e, e);
388 }
389
390 _clearCaches();
391
392 return portlets;
393 }
394
395 public Portlet updatePortlet(
396 long companyId, String portletId, String roles, boolean active)
397 throws SystemException {
398
399 portletId = PortalUtil.getJsSafePortletId(portletId);
400
401 Portlet portlet = portletPersistence.fetchByC_P(companyId, portletId);
402
403 if (portlet == null) {
404 long id = counterLocalService.increment();
405
406 portlet = portletPersistence.create(id);
407
408 portlet.setCompanyId(companyId);
409 portlet.setPortletId(portletId);
410 }
411
412 portlet.setRoles(roles);
413 portlet.setActive(active);
414
415 portletPersistence.update(portlet, false);
416
417 portlet = getPortletById(companyId, portletId);
418
419 portlet.setRoles(roles);
420 portlet.setActive(active);
421
422 return portlet;
423 }
424
425 private void _clearCaches() {
426
427
429 _portletIdsByStrutsPath.clear();
430
431
433 _companyPortletsPool.clear();
434 }
435
436 private List<FriendlyURLMapper> _getFriendlyURLMappers() {
437 List<FriendlyURLMapper> friendlyURLMappers =
438 new ArrayList<FriendlyURLMapper>(
439 _friendlyURLMapperPortlets.size());
440
441 Iterator<Map.Entry<String, Portlet>> itr =
442 _friendlyURLMapperPortlets.entrySet().iterator();
443
444 while (itr.hasNext()) {
445 Map.Entry<String, Portlet> entry = itr.next();
446
447 Portlet portlet = entry.getValue();
448
449 FriendlyURLMapper friendlyURLMapper =
450 portlet.getFriendlyURLMapperInstance();
451
452 if (friendlyURLMapper != null) {
453 friendlyURLMappers.add(friendlyURLMapper);
454 }
455 }
456
457 return friendlyURLMappers;
458 }
459
460 private PortletApp _getPortletApp(String servletContextName) {
461 PortletApp portletApp = _portletAppsPool.get(servletContextName);
462
463 if (portletApp == null) {
464 portletApp = new PortletAppImpl(servletContextName);
465
466 _portletAppsPool.put(servletContextName, portletApp);
467 }
468
469 return portletApp;
470 }
471
472 private String _getPortletId(String securityPath) {
473 if (_portletIdsByStrutsPath.size() == 0) {
474 Iterator<Portlet> itr = _getPortletsPool().values().iterator();
475
476 while (itr.hasNext()) {
477 Portlet portlet = itr.next();
478
479 _portletIdsByStrutsPath.put(
480 portlet.getStrutsPath(), portlet.getPortletId());
481 }
482 }
483
484 String portletId = _portletIdsByStrutsPath.get(securityPath);
485
486 if (Validator.isNull(portletId)) {
487 _log.error(
488 "Struts path " + securityPath + " is not mapped to a portlet " +
489 "in liferay-portlet.xml");
490 }
491
492 return portletId;
493 }
494
495 private List<Portlet> _getPortletsByPortletName(
496 String portletName, String servletContextName,
497 Map<String, Portlet> portletsPool) {
498
499 List<Portlet> portlets = null;
500
501 int pos = portletName.indexOf(StringPool.STAR);
502
503 if (pos == -1) {
504 portlets = new ArrayList<Portlet>();
505
506 String portletId = portletName;
507
508 if (Validator.isNotNull(servletContextName)) {
509 portletId =
510 portletId + PortletConstants.WAR_SEPARATOR +
511 servletContextName;
512 }
513
514 portletId = PortalUtil.getJsSafePortletId(portletId);
515
516 Portlet portlet = portletsPool.get(portletId);
517
518 if (portlet != null) {
519 portlets.add(portlet);
520 }
521
522 return portlets;
523 }
524
525 String portletNamePrefix = portletName.substring(0, pos);
526
527 portlets = _getPortletsByServletContextName(
528 servletContextName, portletsPool);
529
530 Iterator<Portlet> itr = portlets.iterator();
531
532 while (itr.hasNext()) {
533 Portlet portlet = itr.next();
534
535 if (!portlet.getPortletId().startsWith(portletNamePrefix)) {
536 itr.remove();
537 }
538 }
539
540 return portlets;
541 }
542
543 private List<Portlet> _getPortletsByServletContextName(
544 String servletContextName, Map<String, Portlet> portletsPool) {
545
546 List<Portlet> portlets = new ArrayList<Portlet>();
547
548 Iterator<Map.Entry<String, Portlet>> itr =
549 portletsPool.entrySet().iterator();
550
551 while (itr.hasNext()) {
552 Map.Entry<String, Portlet> entry = itr.next();
553
554 String portletId = entry.getKey();
555 Portlet portlet = entry.getValue();
556
557 if (Validator.isNotNull(servletContextName)) {
558 if (portletId.endsWith(
559 PortletConstants.WAR_SEPARATOR + servletContextName)) {
560
561 portlets.add(portlet);
562 }
563 }
564 else {
565 if (portletId.indexOf(PortletConstants.WAR_SEPARATOR) == -1) {
566 portlets.add(portlet);
567 }
568 }
569 }
570
571 return portlets;
572 }
573
574 private Map<String, Portlet> _getPortletsPool() {
575 return _portletsPool;
576 }
577
578 private Map<String, Portlet> _getPortletsPool(long companyId)
579 throws SystemException {
580
581 Map<String, Portlet> portletsPool = _companyPortletsPool.get(companyId);
582
583 if (portletsPool == null) {
584 portletsPool = new ConcurrentHashMap<String, Portlet>();
585
586 Map<String, Portlet> parentPortletsPool = _getPortletsPool();
587
588 if (parentPortletsPool == null) {
589
590
594 return portletsPool;
595 }
596
597 Iterator<Portlet> itr = parentPortletsPool.values().iterator();
598
599 while (itr.hasNext()) {
600 Portlet portlet = itr.next();
601
602 portlet = (Portlet)portlet.clone();
603
604 portlet.setCompanyId(companyId);
605
606 portletsPool.put(portlet.getPortletId(), portlet);
607 }
608
609 itr = portletPersistence.findByCompanyId(companyId).iterator();
610
611 while (itr.hasNext()) {
612 Portlet portlet = itr.next();
613
614 Portlet portletModel = portletsPool.get(portlet.getPortletId());
615
616
619 if (portletModel != null) {
620 portletModel.setPluginPackage(portlet.getPluginPackage());
621 portletModel.setDefaultPluginSetting(
622 portlet.getDefaultPluginSetting());
623 portletModel.setRoles(portlet.getRoles());
624 portletModel.setActive(portlet.getActive());
625 }
626 }
627
628 _companyPortletsPool.put(companyId, portletsPool);
629 }
630
631 return portletsPool;
632 }
633
634 private void _readLiferayDisplay(
635 String servletContextName, Element el, PortletCategory portletCategory,
636 Set<String> portletIds) {
637
638 Iterator<Element> itr1 = el.elements("category").iterator();
639
640 while (itr1.hasNext()) {
641 Element category = itr1.next();
642
643 String name = category.attributeValue("name");
644
645 PortletCategory curPortletCategory = new PortletCategory(name);
646
647 portletCategory.addCategory(curPortletCategory);
648
649 Set<String> curPortletIds = curPortletCategory.getPortletIds();
650
651 Iterator<Element> itr2 = category.elements("portlet").iterator();
652
653 while (itr2.hasNext()) {
654 Element portlet = itr2.next();
655
656 String portletId = portlet.attributeValue("id");
657
658 if (Validator.isNotNull(servletContextName)) {
659 portletId =
660 portletId + PortletConstants.WAR_SEPARATOR +
661 servletContextName;
662 }
663
664 portletId = PortalUtil.getJsSafePortletId(portletId);
665
666 portletIds.add(portletId);
667 curPortletIds.add(portletId);
668 }
669
670 _readLiferayDisplay(
671 servletContextName, category, curPortletCategory, portletIds);
672 }
673 }
674
675 private PortletCategory _readLiferayDisplayXML(String xml)
676 throws Exception {
677
678 return _readLiferayDisplayXML(null, xml);
679 }
680
681 private PortletCategory _readLiferayDisplayXML(
682 String servletContextName, String xml)
683 throws Exception {
684
685 PortletCategory portletCategory = new PortletCategory();
686
687 if (xml == null) {
688 xml = ContentUtil.get(
689 "com/liferay/portal/deploy/dependencies/liferay-display.xml");
690 }
691
692 Document doc = SAXReaderUtil.read(xml, true);
693
694 Element root = doc.getRootElement();
695
696 Set<String> portletIds = new HashSet<String>();
697
698 _readLiferayDisplay(
699 servletContextName, root, portletCategory, portletIds);
700
701
704 Set<String> undefinedPortletIds = new HashSet<String>();
705
706 Iterator<Portlet> itr = _getPortletsPool().values().iterator();
707
708 while (itr.hasNext()) {
709 Portlet portlet = itr.next();
710
711 String portletId = portlet.getPortletId();
712
713 PortletApp portletApp = portlet.getPortletApp();
714
715 if ((servletContextName != null) && (portletApp.isWARFile()) &&
716 (portletId.endsWith(
717 PortletConstants.WAR_SEPARATOR +
718 PortalUtil.getJsSafePortletId(servletContextName)) &&
719 (!portletIds.contains(portletId)))) {
720
721 undefinedPortletIds.add(portletId);
722 }
723 else if ((servletContextName == null) &&
724 (!portletApp.isWARFile()) &&
725 (portletId.indexOf(
726 PortletConstants.WAR_SEPARATOR) == -1) &&
727 (!portletIds.contains(portletId))) {
728
729 undefinedPortletIds.add(portletId);
730 }
731 }
732
733 if (undefinedPortletIds.size() > 0) {
734 PortletCategory undefinedCategory = new PortletCategory(
735 "category.undefined");
736
737 portletCategory.addCategory(undefinedCategory);
738
739 undefinedCategory.getPortletIds().addAll(undefinedPortletIds);
740 }
741
742 return portletCategory;
743 }
744
745 private Set<String> _readLiferayPortletXML(
746 String xml, Map<String, Portlet> portletsPool)
747 throws Exception {
748
749 return _readLiferayPortletXML(StringPool.BLANK, xml, portletsPool);
750 }
751
752 private Set<String> _readLiferayPortletXML(
753 String servletContextName, String xml,
754 Map<String, Portlet> portletsPool)
755 throws Exception {
756
757 Set<String> liferayPortletIds = new HashSet<String>();
758
759 if (xml == null) {
760 return liferayPortletIds;
761 }
762
763 Document doc = SAXReaderUtil.read(xml, true);
764
765 Element root = doc.getRootElement();
766
767 PortletApp portletApp = _getPortletApp(servletContextName);
768
769 Map<String, String> roleMappers = new HashMap<String, String>();
770
771 Iterator<Element> itr1 = root.elements("role-mapper").iterator();
772
773 while (itr1.hasNext()) {
774 Element roleMapper = itr1.next();
775
776 String roleName = roleMapper.elementText("role-name");
777 String roleLink = roleMapper.elementText("role-link");
778
779 roleMappers.put(roleName, roleLink);
780 }
781
782 Map<String, String> customUserAttributes =
783 portletApp.getCustomUserAttributes();
784
785 itr1 = root.elements("custom-user-attribute").iterator();
786
787 while (itr1.hasNext()) {
788 Element customUserAttribute = itr1.next();
789
790 String customClass = customUserAttribute.elementText(
791 "custom-class");
792
793 Iterator<Element> itr2 = customUserAttribute.elements(
794 "name").iterator();
795
796 while (itr2.hasNext()) {
797 Element nameEl = itr2.next();
798
799 String name = nameEl.getText();
800
801 customUserAttributes.put(name, customClass);
802 }
803 }
804
805 itr1 = root.elements("portlet").iterator();
806
807 while (itr1.hasNext()) {
808 Element portlet = itr1.next();
809
810 String portletId = portlet.elementText("portlet-name");
811
812 if (Validator.isNotNull(servletContextName)) {
813 portletId =
814 portletId + PortletConstants.WAR_SEPARATOR +
815 servletContextName;
816 }
817
818 portletId = PortalUtil.getJsSafePortletId(portletId);
819
820 if (_log.isDebugEnabled()) {
821 _log.debug("Reading portlet extension " + portletId);
822 }
823
824 liferayPortletIds.add(portletId);
825
826 Portlet portletModel = portletsPool.get(portletId);
827
828 if (portletModel != null) {
829 portletModel.setIcon(GetterUtil.getString(
830 portlet.elementText("icon"), portletModel.getIcon()));
831 portletModel.setVirtualPath(GetterUtil.getString(
832 portlet.elementText("virtual-path"),
833 portletModel.getVirtualPath()));
834 portletModel.setStrutsPath(GetterUtil.getString(
835 portlet.elementText("struts-path"),
836 portletModel.getStrutsPath()));
837
838 if (Validator.isNotNull(
839 portlet.elementText("configuration-path"))) {
840
841 _log.error(
842 "The configuration-path element is no longer " +
843 "supported. Use configuration-action-class " +
844 "instead.");
845 }
846
847 portletModel.setConfigurationActionClass(GetterUtil.getString(
848 portlet.elementText("configuration-action-class"),
849 portletModel.getConfigurationActionClass()));
850 portletModel.setIndexerClass(GetterUtil.getString(
851 portlet.elementText("indexer-class"),
852 portletModel.getIndexerClass()));
853 portletModel.setOpenSearchClass(GetterUtil.getString(
854 portlet.elementText("open-search-class"),
855 portletModel.getOpenSearchClass()));
856 portletModel.setSchedulerClass(GetterUtil.getString(
857 portlet.elementText("scheduler-class"),
858 portletModel.getSchedulerClass()));
859 portletModel.setPortletURLClass(GetterUtil.getString(
860 portlet.elementText("portlet-url-class"),
861 portletModel.getPortletURLClass()));
862
863 portletModel.setFriendlyURLMapperClass(GetterUtil.getString(
864 portlet.elementText("friendly-url-mapper-class"),
865 portletModel.getFriendlyURLMapperClass()));
866
867 if (Validator.isNull(
868 portletModel.getFriendlyURLMapperClass())) {
869
870 _friendlyURLMapperPortlets.remove(portletId);
871 }
872 else {
873 _friendlyURLMapperPortlets.put(portletId, portletModel);
874 }
875
876 portletModel.setURLEncoderClass(GetterUtil.getString(
877 portlet.elementText("url-encoder-class"),
878 portletModel.getURLEncoderClass()));
879 portletModel.setPortletDataHandlerClass(GetterUtil.getString(
880 portlet.elementText("portlet-data-handler-class"),
881 portletModel.getPortletDataHandlerClass()));
882 portletModel.setPortletLayoutListenerClass(GetterUtil.getString(
883 portlet.elementText("portlet-layout-listener-class"),
884 portletModel.getPortletLayoutListenerClass()));
885 portletModel.setPopMessageListenerClass(GetterUtil.getString(
886 portlet.elementText("pop-message-listener-class"),
887 portletModel.getPopMessageListenerClass()));
888 portletModel.setSocialActivityInterpreterClass(
889 GetterUtil.getString(
890 portlet.elementText(
891 "social-activity-interpreter-class"),
892 portletModel.getSocialActivityInterpreterClass()));
893 portletModel.setSocialRequestInterpreterClass(
894 GetterUtil.getString(
895 portlet.elementText(
896 "social-request-interpreter-class"),
897 portletModel.getSocialRequestInterpreterClass()));
898 portletModel.setPreferencesCompanyWide(GetterUtil.getBoolean(
899 portlet.elementText("preferences-company-wide"),
900 portletModel.isPreferencesCompanyWide()));
901 portletModel.setPreferencesUniquePerLayout(
902 GetterUtil.getBoolean(
903 portlet.elementText("preferences-unique-per-layout"),
904 portletModel.isPreferencesUniquePerLayout()));
905 portletModel.setPreferencesOwnedByGroup(GetterUtil.getBoolean(
906 portlet.elementText("preferences-owned-by-group"),
907 portletModel.isPreferencesOwnedByGroup()));
908 portletModel.setUseDefaultTemplate(GetterUtil.getBoolean(
909 portlet.elementText("use-default-template"),
910 portletModel.isUseDefaultTemplate()));
911 portletModel.setShowPortletAccessDenied(GetterUtil.getBoolean(
912 portlet.elementText("show-portlet-access-denied"),
913 portletModel.isShowPortletAccessDenied()));
914 portletModel.setShowPortletInactive(GetterUtil.getBoolean(
915 portlet.elementText("show-portlet-inactive"),
916 portletModel.isShowPortletInactive()));
917 portletModel.setActionURLRedirect(GetterUtil.getBoolean(
918 portlet.elementText("action-url-redirect"),
919 portletModel.isActionURLRedirect()));
920 portletModel.setRestoreCurrentView(GetterUtil.getBoolean(
921 portlet.elementText("restore-current-view"),
922 portletModel.isRestoreCurrentView()));
923 portletModel.setMaximizeEdit(GetterUtil.getBoolean(
924 portlet.elementText("maximize-edit"),
925 portletModel.isMaximizeEdit()));
926 portletModel.setMaximizeHelp(GetterUtil.getBoolean(
927 portlet.elementText("maximize-help"),
928 portletModel.isMaximizeHelp()));
929 portletModel.setPopUpPrint(GetterUtil.getBoolean(
930 portlet.elementText("pop-up-print"),
931 portletModel.isPopUpPrint()));
932 portletModel.setLayoutCacheable(GetterUtil.getBoolean(
933 portlet.elementText("layout-cacheable"),
934 portletModel.isLayoutCacheable()));
935 portletModel.setInstanceable(GetterUtil.getBoolean(
936 portlet.elementText("instanceable"),
937 portletModel.isInstanceable()));
938 portletModel.setUserPrincipalStrategy(GetterUtil.getString(
939 portlet.elementText("user-principal-strategy"),
940 portletModel.getUserPrincipalStrategy()));
941 portletModel.setPrivateRequestAttributes(GetterUtil.getBoolean(
942 portlet.elementText("private-request-attributes"),
943 portletModel.isPrivateRequestAttributes()));
944 portletModel.setPrivateSessionAttributes(GetterUtil.getBoolean(
945 portlet.elementText("private-session-attributes"),
946 portletModel.isPrivateSessionAttributes()));
947 portletModel.setRenderWeight(GetterUtil.getInteger(
948 portlet.elementText("render-weight"),
949 portletModel.getRenderWeight()));
950 portletModel.setAjaxable(GetterUtil.getBoolean(
951 portlet.elementText("ajaxable"),
952 portletModel.isAjaxable()));
953
954 List<String> headerPortalCssList =
955 portletModel.getHeaderPortalCss();
956
957 Iterator<Element> itr2 = portlet.elements(
958 "header-portal-css").iterator();
959
960 while (itr2.hasNext()) {
961 Element headerPortalCssEl = itr2.next();
962
963 headerPortalCssList.add(headerPortalCssEl.getText());
964 }
965
966 List<String> headerPortletCssList =
967 portletModel.getHeaderPortletCss();
968
969 List<Element> list = new ArrayList<Element>();
970
971 list.addAll(portlet.elements("header-css"));
972 list.addAll(portlet.elements("header-portlet-css"));
973
974 itr2 = list.iterator();
975
976 while (itr2.hasNext()) {
977 Element headerPortletCssEl = itr2.next();
978
979 headerPortletCssList.add(headerPortletCssEl.getText());
980 }
981
982 List<String> headerPortalJavaScriptList =
983 portletModel.getHeaderPortalJavaScript();
984
985 itr2 = portlet.elements("header-portal-javascript").iterator();
986
987 while (itr2.hasNext()) {
988 Element headerPortalJavaScriptEl = itr2.next();
989
990 headerPortalJavaScriptList.add(
991 headerPortalJavaScriptEl.getText());
992 }
993
994 List<String> headerPortletJavaScriptList =
995 portletModel.getHeaderPortletJavaScript();
996
997 list.clear();
998
999 list.addAll(portlet.elements("header-javascript"));
1000 list.addAll(portlet.elements("header-portlet-javascript"));
1001
1002 itr2 = list.iterator();
1003
1004 while (itr2.hasNext()) {
1005 Element headerPortletJavaScriptEl = itr2.next();
1006
1007 headerPortletJavaScriptList.add(
1008 headerPortletJavaScriptEl.getText());
1009 }
1010
1011 List<String> footerPortalCssList =
1012 portletModel.getFooterPortalCss();
1013
1014 itr2 = portlet.elements("footer-portal-css").iterator();
1015
1016 while (itr2.hasNext()) {
1017 Element footerPortalCssEl = itr2.next();
1018
1019 footerPortalCssList.add(footerPortalCssEl.getText());
1020 }
1021
1022 List<String> footerPortletCssList =
1023 portletModel.getFooterPortletCss();
1024
1025 itr2 = portlet.elements("footer-portlet-css").iterator();
1026
1027 while (itr2.hasNext()) {
1028 Element footerPortletCssEl = itr2.next();
1029
1030 footerPortletCssList.add(footerPortletCssEl.getText());
1031 }
1032
1033 List<String> footerPortalJavaScriptList =
1034 portletModel.getFooterPortalJavaScript();
1035
1036 itr2 = portlet.elements("footer-portal-javascript").iterator();
1037
1038 while (itr2.hasNext()) {
1039 Element footerPortalJavaScriptEl = itr2.next();
1040
1041 footerPortalJavaScriptList.add(
1042 footerPortalJavaScriptEl.getText());
1043 }
1044
1045 List<String> footerPortletJavaScriptList =
1046 portletModel.getFooterPortletJavaScript();
1047
1048 itr2 = portlet.elements("footer-portlet-javascript").iterator();
1049
1050 while (itr2.hasNext()) {
1051 Element footerPortletJavaScriptEl = itr2.next();
1052
1053 footerPortletJavaScriptList.add(
1054 footerPortletJavaScriptEl.getText());
1055 }
1056
1057 portletModel.setCssClassWrapper(GetterUtil.getString(
1058 portlet.elementText("css-class-wrapper"),
1059 portletModel.getCssClassWrapper()));
1060 portletModel.setFacebookIntegration(GetterUtil.getString(
1061 portlet.elementText("facebook-integration"),
1062 portletModel.getFacebookIntegration()));
1063 portletModel.setAddDefaultResource(GetterUtil.getBoolean(
1064 portlet.elementText("add-default-resource"),
1065 portletModel.isAddDefaultResource()));
1066 portletModel.setSystem(GetterUtil.getBoolean(
1067 portlet.elementText("system"),
1068 portletModel.isSystem()));
1069 portletModel.setActive(GetterUtil.getBoolean(
1070 portlet.elementText("active"),
1071 portletModel.isActive()));
1072 portletModel.setInclude(GetterUtil.getBoolean(
1073 portlet.elementText("include"),
1074 portletModel.isInclude()));
1075
1076 if (!portletModel.isAjaxable() &&
1077 (portletModel.getRenderWeight() < 1)) {
1078
1079 portletModel.setRenderWeight(1);
1080 }
1081
1082 portletModel.getRoleMappers().putAll(roleMappers);
1083 portletModel.linkRoles();
1084 }
1085 }
1086
1087 return liferayPortletIds;
1088 }
1089
1090 private Set<String> _readPortletXML(
1091 String xml, Map<String, Portlet> portletsPool,
1092 List<String> servletURLPatterns, PluginPackage pluginPackage)
1093 throws Exception {
1094
1095 return _readPortletXML(
1096 StringPool.BLANK, xml, portletsPool, servletURLPatterns,
1097 pluginPackage);
1098 }
1099
1100 private Set<String> _readPortletXML(
1101 String servletContextName, String xml,
1102 Map<String, Portlet> portletsPool, List<String> servletURLPatterns,
1103 PluginPackage pluginPackage)
1104 throws Exception {
1105
1106 Set<String> portletIds = new HashSet<String>();
1107
1108 if (xml == null) {
1109 return portletIds;
1110 }
1111
1112 Document doc = SAXReaderUtil.read(
1113 xml, PropsValues.PORTLET_XML_VALIDATE);
1114
1115 Element root = doc.getRootElement();
1116
1117 PortletApp portletApp = _getPortletApp(servletContextName);
1118
1119 portletApp.getServletURLPatterns().addAll(servletURLPatterns);
1120
1121 Set<String> userAttributes = portletApp.getUserAttributes();
1122
1123 Iterator<Element> itr1 = root.elements("user-attribute").iterator();
1124
1125 while (itr1.hasNext()) {
1126 Element userAttribute = itr1.next();
1127
1128 String name = userAttribute.elementText("name");
1129
1130 userAttributes.add(name);
1131 }
1132
1133 String defaultNamespace = root.elementText("default-namespace");
1134
1135 if (Validator.isNotNull(defaultNamespace)) {
1136 portletApp.setDefaultNamespace(defaultNamespace);
1137 }
1138
1139 itr1 = root.elements("event-definition").iterator();
1140
1141 while (itr1.hasNext()) {
1142 Element eventDefinitionEl = itr1.next();
1143
1144 Element qNameEl = eventDefinitionEl.element("qname");
1145 Element nameEl = eventDefinitionEl.element("name");
1146 String valueType = eventDefinitionEl.elementText("value-type");
1147
1148 QName qName = QNameUtil.getQName(
1149 qNameEl, nameEl, portletApp.getDefaultNamespace());
1150
1151 EventDefinition eventDefinition = new EventDefinitionImpl(
1152 qName, valueType, portletApp);
1153
1154 portletApp.addEventDefinition(eventDefinition);
1155 }
1156
1157 itr1 = root.elements("public-render-parameter").iterator();
1158
1159 while (itr1.hasNext()) {
1160 Element publicRenderParameterEl = itr1.next();
1161
1162 String identifier = publicRenderParameterEl.elementText(
1163 "identifier");
1164 Element qNameEl = publicRenderParameterEl.element("qname");
1165 Element nameEl = publicRenderParameterEl.element("name");
1166
1167 QName qName = QNameUtil.getQName(
1168 qNameEl, nameEl, portletApp.getDefaultNamespace());
1169
1170 PublicRenderParameter publicRenderParameter =
1171 new PublicRenderParameterImpl(identifier, qName, portletApp);
1172
1173 portletApp.addPublicRenderParameter(publicRenderParameter);
1174 }
1175
1176 itr1 = root.elements("container-runtime-option").iterator();
1177
1178 while (itr1.hasNext()) {
1179 Element containerRuntimeOption = itr1.next();
1180
1181 String name = containerRuntimeOption.elementText("name");
1182
1183 List<String> values = new ArrayList<String>();
1184
1185 for (Element value : containerRuntimeOption.elements("value")) {
1186 values.add(value.getTextTrim());
1187 }
1188
1189 portletApp.getContainerRuntimeOptions().put(
1190 name, values.toArray(new String[values.size()]));
1191 }
1192
1193 itr1 = root.elements("portlet").iterator();
1194
1195 while (itr1.hasNext()) {
1196 Element portlet = itr1.next();
1197
1198 String portletName = portlet.elementText("portlet-name");
1199
1200 String portletId = portletName;
1201
1202 if (Validator.isNotNull(servletContextName)) {
1203 portletId =
1204 portletId + PortletConstants.WAR_SEPARATOR +
1205 servletContextName;
1206 }
1207
1208 portletId = PortalUtil.getJsSafePortletId(portletId);
1209
1210 if (_log.isDebugEnabled()) {
1211 _log.debug("Reading portlet " + portletId);
1212 }
1213
1214 portletIds.add(portletId);
1215
1216 Portlet portletModel = portletsPool.get(portletId);
1217
1218 if (portletModel == null) {
1219 portletModel = new PortletImpl(
1220 CompanyConstants.SYSTEM, portletId);
1221
1222 portletsPool.put(portletId, portletModel);
1223 }
1224
1225 portletModel.setTimestamp(System.currentTimeMillis());
1226
1227 portletModel.setPluginPackage(pluginPackage);
1228 portletModel.setPortletApp(portletApp);
1229
1230 portletModel.setPortletName(portletName);
1231 portletModel.setDisplayName(GetterUtil.getString(
1232 portlet.elementText("display-name"),
1233 portletModel.getDisplayName()));
1234 portletModel.setPortletClass(GetterUtil.getString(
1235 portlet.elementText("portlet-class")));
1236
1237 Iterator<Element> itr2 = portlet.elements("init-param").iterator();
1238
1239 while (itr2.hasNext()) {
1240 Element initParam = itr2.next();
1241
1242 portletModel.getInitParams().put(
1243 initParam.elementText("name"),
1244 initParam.elementText("value"));
1245 }
1246
1247 Element expirationCache = portlet.element("expiration-cache");
1248
1249 if (expirationCache != null) {
1250 portletModel.setExpCache(new Integer(GetterUtil.getInteger(
1251 expirationCache.getText())));
1252 }
1253
1254 itr2 = portlet.elements("supports").iterator();
1255
1256 while (itr2.hasNext()) {
1257 Element supports = itr2.next();
1258
1259 String mimeType = supports.elementText("mime-type");
1260
1261 Set<String> mimeTypeModes =
1262 portletModel.getPortletModes().get(mimeType);
1263
1264 if (mimeTypeModes == null) {
1265 mimeTypeModes = new HashSet<String>();
1266
1267 portletModel.getPortletModes().put(mimeType, mimeTypeModes);
1268 }
1269
1270 mimeTypeModes.add(PortletMode.VIEW.toString().toLowerCase());
1271
1272 Iterator<Element> itr3 = supports.elements(
1273 "portlet-mode").iterator();
1274
1275 while (itr3.hasNext()) {
1276 Element portletMode = itr3.next();
1277
1278 mimeTypeModes.add(portletMode.getTextTrim().toLowerCase());
1279 }
1280 }
1281
1282 Set<String> supportedLocales = portletModel.getSupportedLocales();
1283
1284
1287 itr2 = portlet.elements("supported-locale").iterator();
1288
1289 while (itr2.hasNext()) {
1290 Element supportedLocaleEl = itr2.next();
1291
1292 String supportedLocale = supportedLocaleEl.getText();
1293
1294 supportedLocales.add(supportedLocale);
1295 }
1296
1297 portletModel.setResourceBundle(
1298 portlet.elementText("resource-bundle"));
1299
1300 Element portletInfo = portlet.element("portlet-info");
1301
1302 String portletInfoTitle = null;
1303 String portletInfoShortTitle = null;
1304 String portletInfoKeyWords = null;
1305
1306 if (portletInfo != null) {
1307 portletInfoTitle = portletInfo.elementText("title");
1308 portletInfoShortTitle = portletInfo.elementText("short-title");
1309 portletInfoKeyWords = portletInfo.elementText("keywords");
1310 }
1311
1312 portletModel.setPortletInfo(new PortletInfo(
1313 portletInfoTitle, portletInfoShortTitle, portletInfoKeyWords));
1314
1315 Element portletPreferences = portlet.element("portlet-preferences");
1316
1317 String defaultPreferences = null;
1318 String prefsValidator = null;
1319
1320 if (portletPreferences != null) {
1321 Element prefsValidatorEl =
1322 portletPreferences.element("preferences-validator");
1323
1324 if (prefsValidatorEl != null) {
1325 prefsValidator = prefsValidatorEl.getText();
1326
1327 portletPreferences.remove(prefsValidatorEl);
1328 }
1329
1330 defaultPreferences = portletPreferences.asXML();
1331 }
1332
1333 portletModel.setDefaultPreferences(defaultPreferences);
1334 portletModel.setPreferencesValidator(prefsValidator);
1335
1336 if (!portletApp.isWARFile() &&
1337 Validator.isNotNull(prefsValidator) &&
1338 PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
1339
1340 try {
1341 PreferencesValidator prefsValidatorObj =
1342 PortalUtil.getPreferencesValidator(portletModel);
1343
1344 prefsValidatorObj.validate(
1345 PortletPreferencesSerializer.fromDefaultXML(
1346 defaultPreferences));
1347 }
1348 catch (Exception e) {
1349 if (_log.isWarnEnabled()) {
1350 _log.warn(
1351 "Portlet with the name " + portletId +
1352 " does not have valid default preferences");
1353 }
1354 }
1355 }
1356
1357 Set<String> unlikedRoles = portletModel.getUnlinkedRoles();
1358
1359 itr2 = portlet.elements("security-role-ref").iterator();
1360
1361 while (itr2.hasNext()) {
1362 Element role = itr2.next();
1363
1364 unlikedRoles.add(role.elementText("role-name"));
1365 }
1366
1367 itr2 = portlet.elements("supported-processing-event").iterator();
1368
1369 while (itr2.hasNext()) {
1370 Element supportedProcessingEvent = itr2.next();
1371
1372 Element qNameEl = supportedProcessingEvent.element("qname");
1373 Element nameEl = supportedProcessingEvent.element("name");
1374
1375 QName qName = QNameUtil.getQName(
1376 qNameEl, nameEl, portletApp.getDefaultNamespace());
1377
1378 portletModel.addProcessingEvent(qName);
1379 }
1380
1381 itr2 = portlet.elements("supported-publishing-event").iterator();
1382
1383 while (itr2.hasNext()) {
1384 Element supportedPublishingEvent = itr2.next();
1385
1386 Element qNameEl = supportedPublishingEvent.element("qname");
1387 Element nameEl = supportedPublishingEvent.element("name");
1388
1389 QName qName = QNameUtil.getQName(
1390 qNameEl, nameEl, portletApp.getDefaultNamespace());
1391
1392 portletModel.addPublishingEvent(qName);
1393 }
1394
1395 itr2 = portlet.elements(
1396 "supported-public-render-parameter").iterator();
1397
1398 while (itr2.hasNext()) {
1399 Element supportedPublicRenderParameter = itr2.next();
1400
1401 String identifier =
1402 supportedPublicRenderParameter.getTextTrim();
1403
1404 PublicRenderParameter publicRenderParameter =
1405 portletApp.getPublicRenderParameter(identifier);
1406
1407 if (publicRenderParameter == null) {
1408 _log.error(
1409 "Supported public render parameter references " +
1410 "unnknown identifier " + identifier);
1411
1412 continue;
1413 }
1414
1415 portletModel.addPublicRenderParameter(publicRenderParameter);
1416 }
1417 }
1418
1419 itr1 = root.elements("filter").iterator();
1420
1421 while (itr1.hasNext()) {
1422 Element filter = itr1.next();
1423
1424 String filterName = filter.elementText("filter-name");
1425 String filterClass = filter.elementText("filter-class");
1426
1427 Set<String> lifecycles = new LinkedHashSet<String>();
1428
1429 Iterator<Element> itr2 = filter.elements("lifecycle").iterator();
1430
1431 while (itr2.hasNext()) {
1432 Element lifecycle = itr2.next();
1433
1434 lifecycles.add(lifecycle.getText());
1435 }
1436
1437 Map<String, String> initParams = new HashMap<String, String>();
1438
1439 itr2 = filter.elements("init-param").iterator();
1440
1441 while (itr2.hasNext()) {
1442 Element initParam = itr2.next();
1443
1444 initParams.put(
1445 initParam.elementText("name"),
1446 initParam.elementText("value"));
1447 }
1448
1449 PortletFilter portletFilter = new PortletFilterImpl(
1450 filterName, filterClass, lifecycles, initParams, portletApp);
1451
1452 portletApp.addPortletFilter(portletFilter);
1453 }
1454
1455 itr1 = root.elements("filter-mapping").iterator();
1456
1457 while (itr1.hasNext()) {
1458 Element filterMapping = itr1.next();
1459
1460 String filterName = filterMapping.elementText("filter-name");
1461
1462 Iterator<Element> itr2 = filterMapping.elements(
1463 "portlet-name").iterator();
1464
1465 while (itr2.hasNext()) {
1466 Element portletNameEl = itr2.next();
1467
1468 String portletName = portletNameEl.getTextTrim();
1469
1470 PortletFilter portletFilter = portletApp.getPortletFilter(
1471 filterName);
1472
1473 if (portletFilter == null) {
1474 _log.error(
1475 "Filter mapping references unnknown filter name " +
1476 filterName);
1477
1478 continue;
1479 }
1480
1481 List<Portlet> portletModels = _getPortletsByPortletName(
1482 portletName, servletContextName, portletsPool);
1483
1484 if (portletModels.size() == 0) {
1485 _log.error(
1486 "Filter mapping with filter name " + filterName +
1487 " references unnknown portlet name " + portletName);
1488 }
1489
1490 for (Portlet portletModel : portletModels) {
1491 portletModel.getPortletFilters().put(
1492 filterName, portletFilter);
1493 }
1494 }
1495 }
1496
1497 itr1 = root.elements("listener").iterator();
1498
1499 while (itr1.hasNext()) {
1500 Element listener = itr1.next();
1501
1502 String listenerClass = listener.elementText("listener-class");
1503
1504 PortletURLListener portletURLListener = new PortletURLListenerImpl(
1505 listenerClass, portletApp);
1506
1507 portletApp.addPortletURLListener(portletURLListener);
1508 }
1509
1510 return portletIds;
1511 }
1512
1513 private List<String> _readWebXML(String xml) throws Exception {
1514 List<String> servletURLPatterns = new ArrayList<String>();
1515
1516 if (xml == null) {
1517 return servletURLPatterns;
1518 }
1519
1520 Document doc = SAXReaderUtil.read(xml);
1521
1522 Element root = doc.getRootElement();
1523
1524 Iterator<Element> itr = root.elements("servlet-mapping").iterator();
1525
1526 while (itr.hasNext()) {
1527 Element servletMapping = itr.next();
1528
1529 String urlPattern = servletMapping.elementText("url-pattern");
1530
1531 servletURLPatterns.add(urlPattern);
1532 }
1533
1534 return servletURLPatterns;
1535
1536 }
1537
1538 private static Log _log = LogFactory.getLog(PortletLocalServiceImpl.class);
1539
1540 private static Map<String, PortletApp> _portletAppsPool =
1541 new ConcurrentHashMap<String, PortletApp>();
1542 private static Map<String, Portlet> _portletsPool =
1543 new ConcurrentHashMap<String, Portlet>();
1544 private static Map<Long, Map<String, Portlet>> _companyPortletsPool =
1545 new ConcurrentHashMap<Long, Map<String, Portlet>>();
1546 private static Map<String, String> _portletIdsByStrutsPath =
1547 new ConcurrentHashMap<String, String>();
1548 private static Map<String, Portlet> _friendlyURLMapperPortlets =
1549 new ConcurrentHashMap<String, Portlet>();
1550
1551}