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