1
14
15 package com.liferay.portal.tools;
16
17 import com.liferay.portal.kernel.plugin.PluginPackage;
18 import com.liferay.portal.kernel.util.FileUtil;
19 import com.liferay.portal.kernel.util.PropsKeys;
20 import com.liferay.portal.kernel.util.ServerDetector;
21 import com.liferay.portal.kernel.util.StringUtil;
22 import com.liferay.portal.kernel.util.Validator;
23 import com.liferay.portal.kernel.xml.Document;
24 import com.liferay.portal.kernel.xml.Element;
25 import com.liferay.portal.kernel.xml.SAXReaderUtil;
26 import com.liferay.portal.model.Plugin;
27 import com.liferay.portal.util.InitUtil;
28 import com.liferay.portal.util.Portal;
29 import com.liferay.portal.util.PortalUtil;
30 import com.liferay.portal.util.PrefsPropsUtil;
31 import com.liferay.portal.util.PropsValues;
32 import com.liferay.portal.xml.DocumentImpl;
33 import com.liferay.util.TextFormatter;
34 import com.liferay.util.bridges.mvc.MVCPortlet;
35 import com.liferay.util.xml.XMLMerger;
36 import com.liferay.util.xml.descriptor.FacesXMLDescriptor;
37
38 import java.io.File;
39
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Properties;
46
47
53 public class PortletDeployer extends BaseDeployer {
54
55 public static final String JSF_MYFACES =
56 "org.apache.myfaces.portlet.MyFacesGenericPortlet";
57
58 public static final String JSF_STANDARD =
59 "javax.portlet.faces.GenericFacesPortlet";
60
61 public static final String JSF_SUN =
62 "com.sun.faces.portlet.FacesPortlet";
63
64 public static final String LIFERAY_RENDER_KIT_FACTORY =
65 "com.liferay.util.jsf.sun.faces.renderkit.LiferayRenderKitFactoryImpl";
66
67 public static final String MYFACES_CONTEXT_FACTORY =
68 "com.liferay.util.bridges.jsf.myfaces.MyFacesContextFactoryImpl";
69
70 public static void main(String[] args) {
71 InitUtil.initWithSpring();
72
73 List<String> wars = new ArrayList<String>();
74 List<String> jars = new ArrayList<String>();
75
76 for (String arg : args) {
77 if (arg.endsWith(".war")) {
78 wars.add(arg);
79 }
80 else if (arg.endsWith(".jar")) {
81 jars.add(arg);
82 }
83 }
84
85 new PortletDeployer(wars, jars);
86 }
87
88 protected PortletDeployer() {
89 }
90
91 protected PortletDeployer(List<String> wars, List<String> jars) {
92 super(wars, jars);
93 }
94
95 protected void checkArguments() {
96 super.checkArguments();
97
98 if (Validator.isNull(portletTaglibDTD)) {
99 throw new IllegalArgumentException(
100 "The system property deployer.portlet.taglib.dtd is not set");
101 }
102 }
103
104 protected void copyXmls(
105 File srcFile, String displayName, PluginPackage pluginPackage)
106 throws Exception {
107
108 super.copyXmls(srcFile, displayName, pluginPackage);
109
110 if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
111 copyDependencyXml("context.xml", srcFile + "/META-INF");
112 }
113 }
114
115 protected String getExtraContent(
116 double webXmlVersion, File srcFile, String displayName)
117 throws Exception {
118
119 StringBuilder sb = new StringBuilder();
120
121 String extraContent = super.getExtraContent(
122 webXmlVersion, srcFile, displayName);
123
124 sb.append(extraContent);
125
126 if (ServerDetector.isWebSphere()) {
127 sb.append("<context-param>");
128 sb.append("<param-name>");
129 sb.append("com.ibm.websphere.portletcontainer.");
130 sb.append("PortletDeploymentEnabled");
131 sb.append("</param-name>");
132 sb.append("<param-value>false</param-value>");
133 sb.append("</context-param>");
134 }
135
136 File facesXML = new File(srcFile + "/WEB-INF/faces-config.xml");
137 File portletXML = new File(
138 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
139 File webXML = new File(srcFile + "/WEB-INF/web.xml");
140
141 updatePortletXML(portletXML);
142
143 sb.append(getServletContent(portletXML, webXML));
144
145 setupJSF(facesXML, portletXML);
146
147 if (_sunFacesPortlet) {
148
149
151 sb.append("<listener>");
152 sb.append("<listener-class>");
153 sb.append("com.liferay.util.bridges.jsf.sun.");
154 sb.append("LiferayConfigureListener");
155 sb.append("</listener-class>");
156 sb.append("</listener>");
157 }
158
159
161 sb.append("<listener>");
162 sb.append("<listener-class>");
163 sb.append("com.liferay.portal.kernel.servlet.PortletContextListener");
164 sb.append("</listener-class>");
165 sb.append("</listener>");
166
167
169 sb.append(getSpeedFiltersContent(srcFile));
170
171 return sb.toString();
172 }
173
174 protected String getServletContent(File portletXML, File webXML)
175 throws Exception {
176
177 StringBuilder sb = new StringBuilder();
178
179
181 Document doc = SAXReaderUtil.read(portletXML);
182
183 Element root = doc.getRootElement();
184
185 Iterator<Element> itr1 = root.elements("portlet").iterator();
186
187 while (itr1.hasNext()) {
188 Element portlet = itr1.next();
189
190 String portletName = PortalUtil.getJsSafePortletId(
191 portlet.elementText("portlet-name"));
192 String portletClass = portlet.elementText("portlet-class");
193
194 sb.append("<servlet>");
195 sb.append("<servlet-name>");
196 sb.append(portletName);
197 sb.append("</servlet-name>");
198 sb.append("<servlet-class>");
199 sb.append("com.liferay.portal.kernel.servlet.PortletServlet");
200 sb.append("</servlet-class>");
201 sb.append("<init-param>");
202 sb.append("<param-name>portlet-class</param-name>");
203 sb.append("<param-value>");
204 sb.append(portletClass);
205 sb.append("</param-value>");
206 sb.append("</init-param>");
207 sb.append("<load-on-startup>0</load-on-startup>");
208 sb.append("</servlet>");
209
210 sb.append("<servlet-mapping>");
211 sb.append("<servlet-name>");
212 sb.append(portletName);
213 sb.append("</servlet-name>");
214 sb.append("<url-pattern>/");
215 sb.append(portletName);
216 sb.append("/*</url-pattern>");
217 sb.append("</servlet-mapping>");
218 }
219
220
222 doc = SAXReaderUtil.read(webXML);
223
224 root = doc.getRootElement();
225
226
228 itr1 = root.elements("servlet").iterator();
229
230 while (itr1.hasNext()) {
231 Element servlet = itr1.next();
232
233 String icon = servlet.elementText("icon");
234 String servletName = servlet.elementText("servlet-name");
235 String displayName = servlet.elementText("display-name");
236 String description = servlet.elementText("description");
237 String servletClass = servlet.elementText("servlet-class");
238 List<Element> initParams = servlet.elements("init-param");
239 String loadOnStartup = servlet.elementText("load-on-startup");
240 String runAs = servlet.elementText("run-as");
241 List<Element> securityRoleRefs = servlet.elements(
242 "security-role-ref");
243
244 if ((servletClass != null) &&
245 (servletClass.equals(
246 "com.liferay.portal.servlet.SharedServletWrapper"))) {
247
248 sb.append("<servlet>");
249
250 if (icon != null) {
251 sb.append("<icon>");
252 sb.append(icon);
253 sb.append("</icon>");
254 }
255
256 if (servletName != null) {
257 sb.append("<servlet-name>");
258 sb.append(servletName);
259 sb.append("</servlet-name>");
260 }
261
262 if (displayName != null) {
263 sb.append("<display-name>");
264 sb.append(displayName);
265 sb.append("</display-name>");
266 }
267
268 if (description != null) {
269 sb.append("<description>");
270 sb.append(description);
271 sb.append("</description>");
272 }
273
274 Iterator<Element> itr2 = initParams.iterator();
275
276 while (itr2.hasNext()) {
277 Element initParam = itr2.next();
278
279 String paramName = initParam.elementText("param-name");
280 String paramValue = initParam.elementText("param-value");
281
282 if ((paramName != null) &&
283 (paramName.equals("servlet-class"))) {
284
285 sb.append("<servlet-class>");
286 sb.append(paramValue);
287 sb.append("</servlet-class>");
288 }
289 }
290
291 itr2 = initParams.iterator();
292
293 while (itr2.hasNext()) {
294 Element initParam = itr2.next();
295
296 String paramName = initParam.elementText("param-name");
297 String paramValue = initParam.elementText("param-value");
298 String paramDesc = initParam.elementText("description");
299
300 if ((paramName != null) &&
301 (!paramName.equals("servlet-class"))) {
302
303 sb.append("<init-param>");
304 sb.append("<param-name>");
305 sb.append(paramName);
306 sb.append("</param-name>");
307
308 if (paramValue != null) {
309 sb.append("<param-value>");
310 sb.append(paramValue);
311 sb.append("</param-value>");
312 }
313
314 if (paramDesc != null) {
315 sb.append("<description>");
316 sb.append(paramDesc);
317 sb.append("</description>");
318 }
319
320 sb.append("</init-param>");
321 }
322 }
323
324 if (loadOnStartup != null) {
325 sb.append("<load-on-startup>");
326 sb.append(loadOnStartup);
327 sb.append("</load-on-startup>");
328 }
329
330 if (runAs != null) {
331 sb.append("<run-as>");
332 sb.append(runAs);
333 sb.append("</run-as>");
334 }
335
336 itr2 = securityRoleRefs.iterator();
337
338 while (itr2.hasNext()) {
339 Element roleRef = itr2.next();
340
341 String roleDesc = roleRef.elementText("description");
342 String roleName = roleRef.elementText("role-name");
343 String roleLink = roleRef.elementText("role-link");
344
345 sb.append("<security-role-ref>");
346
347 if (roleDesc != null) {
348 sb.append("<description>");
349 sb.append(roleDesc);
350 sb.append("</description>");
351 }
352
353 if (roleName != null) {
354 sb.append("<role-name>");
355 sb.append(roleName);
356 sb.append("</role-name>");
357 }
358
359 if (roleLink != null) {
360 sb.append("<role-link>");
361 sb.append(roleLink);
362 sb.append("</role-link>");
363 }
364
365 sb.append("</security-role-ref>");
366 }
367
368 sb.append("</servlet>");
369 }
370 }
371
372 return sb.toString();
373 }
374
375 protected void processPluginPackageProperties(
376 File srcFile, String displayName, PluginPackage pluginPackage)
377 throws Exception {
378
379 if (pluginPackage == null) {
380 return;
381 }
382
383 Properties props = getPluginPackageProperties(srcFile);
384
385 if ((props == null) || (props.size() == 0)) {
386 return;
387 }
388
389 String moduleGroupId = pluginPackage.getGroupId();
390 String moduleArtifactId = pluginPackage.getArtifactId();
391 String moduleVersion = pluginPackage.getVersion();
392
393 String pluginName = pluginPackage.getName();
394 String pluginType = pluginPackage.getTypes().get(0);
395 String pluginTypeName = TextFormatter.format(
396 pluginType, TextFormatter.J);
397
398 if (!pluginType.equals(Plugin.TYPE_PORTLET)) {
399 return;
400 }
401
402 String tags = getPluginPackageTagsXml(pluginPackage.getTags());
403 String shortDescription = pluginPackage.getShortDescription();
404 String longDescription = pluginPackage.getLongDescription();
405 String changeLog = pluginPackage.getChangeLog();
406 String pageURL = pluginPackage.getPageURL();
407 String author = pluginPackage.getAuthor();
408 String licenses = getPluginPackageLicensesXml(
409 pluginPackage.getLicenses());
410 String liferayVersions = getPluginPackageLiferayVersionsXml(
411 pluginPackage.getLiferayVersions());
412
413 Map<String, String> filterMap = new HashMap<String, String>();
414
415 filterMap.put("module_group_id", moduleGroupId);
416 filterMap.put("module_artifact_id", moduleArtifactId);
417 filterMap.put("module_version", moduleVersion);
418
419 filterMap.put("plugin_name", pluginName);
420 filterMap.put("plugin_type", pluginType);
421 filterMap.put("plugin_type_name", pluginTypeName);
422
423 filterMap.put("tags", tags);
424 filterMap.put("short_description", shortDescription);
425 filterMap.put("long_description", longDescription);
426 filterMap.put("change_log", changeLog);
427 filterMap.put("page_url", pageURL);
428 filterMap.put("author", author);
429 filterMap.put("licenses", licenses);
430 filterMap.put("liferay_versions", liferayVersions);
431
432 copyDependencyXml(
433 "liferay-plugin-package.xml", srcFile + "/WEB-INF", filterMap,
434 true);
435 }
436
437 protected void setupJSF(File facesXML, File portletXML) throws Exception {
438 _myFacesPortlet = false;
439 _sunFacesPortlet = false;
440
441 if (!facesXML.exists()) {
442 return;
443 }
444
445
447 Document doc = SAXReaderUtil.read(portletXML, true);
448
449 Element root = doc.getRootElement();
450
451 List<Element> elements = root.elements("portlet");
452
453 Iterator<Element> itr = elements.iterator();
454
455 while (itr.hasNext()) {
456 Element portlet = itr.next();
457
458 String portletClass = portlet.elementText("portlet-class");
459
460 if (portletClass.equals(JSF_MYFACES)) {
461 _myFacesPortlet = true;
462
463 break;
464 }
465 else if (portletClass.equals(JSF_SUN)) {
466 _sunFacesPortlet = true;
467
468 break;
469 }
470 }
471
472
474 doc = SAXReaderUtil.read(facesXML, true);
475
476 root = doc.getRootElement();
477
478 Element factoryEl = root.element("factory");
479
480 Element renderKitFactoryEl = null;
481 Element facesContextFactoryEl = null;
482
483 if (factoryEl == null) {
484 factoryEl = root.addElement("factory");
485 }
486
487 renderKitFactoryEl = factoryEl.element("render-kit-factory");
488 facesContextFactoryEl = factoryEl.element("faces-context-factory");
489
490 if ((appServerType.equals("orion") && (_sunFacesPortlet) &&
491 (renderKitFactoryEl == null))) {
492
493 renderKitFactoryEl = factoryEl.addElement("render-kit-factory");
494
495 renderKitFactoryEl.addText(LIFERAY_RENDER_KIT_FACTORY);
496 }
497 else if (_myFacesPortlet && (facesContextFactoryEl == null)) {
498 facesContextFactoryEl =
499 factoryEl.addElement("faces-context-factory");
500
501 facesContextFactoryEl.addText(MYFACES_CONTEXT_FACTORY);
502 }
503
504 if (!appServerType.equals("orion") && (_sunFacesPortlet)) {
505 factoryEl.detach();
506 }
507
508 XMLMerger merger = new XMLMerger(new FacesXMLDescriptor());
509
510 DocumentImpl docImpl = (DocumentImpl)doc;
511
512 merger.organizeXML(docImpl.getWrappedDocument());
513
514 FileUtil.write(facesXML, doc.formattedString(), true);
515 }
516
517 protected void updateDeployDirectory(File srcFile) throws Exception {
518 try {
519 if (!PrefsPropsUtil.getBoolean(
520 PropsKeys.AUTO_DEPLOY_CUSTOM_PORTLET_XML,
521 PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML)) {
522
523 return;
524 }
525 }
526 catch (Exception e) {
527
528
532 if (!PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML) {
533 return;
534 }
535 }
536
537 File portletXML = new File(
538 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
539
540 if (portletXML.exists()) {
541 File portletCustomXML = new File(
542 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM);
543
544 if (portletCustomXML.exists()) {
545 portletCustomXML.delete();
546 }
547
548 portletXML.renameTo(portletCustomXML);
549 }
550 }
551
552 protected void updatePortletXML(File portletXML) throws Exception {
553 if (!portletXML.exists()) {
554 return;
555 }
556
557 String content = FileUtil.read(portletXML);
558
559 content = StringUtil.replace(
560 content, "com.liferay.util.bridges.jsp.JSPPortlet",
561 MVCPortlet.class.getName());
562
563 FileUtil.write(portletXML, content);
564 }
565
566 private boolean _myFacesPortlet;
567 private boolean _sunFacesPortlet;
568
569 }