/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * *******************************************************************************/ package com.liferay.ide.portlet.core.dd; import com.liferay.ide.core.ILiferayConstants; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.core.util.NodeUtil; import com.liferay.ide.core.util.StringPool; import com.liferay.ide.portlet.core.operation.INewPortletClassDataModelProperties; import com.liferay.ide.project.core.descriptor.AddNewPortletOperation; import com.liferay.ide.project.core.descriptor.LiferayDescriptorHelper; import com.liferay.ide.project.core.descriptor.RemoveAllPortletsOperation; import com.liferay.ide.project.core.descriptor.RemoveSampleElementsOperation; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jst.j2ee.common.ParamValue; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Gregory Amerson * @author Cindy Li * @author Simon Jiang * @author Kuo Zhang * @author Terry Jia */ @SuppressWarnings( { "restriction", "unchecked" } ) public class PortletDescriptorHelper extends LiferayDescriptorHelper implements INewPortletClassDataModelProperties { public static final String DESCRIPTOR_FILE = ILiferayConstants.PORTLET_XML_FILE; private static final String DESCRIPTOR_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<portlet-app xmlns=\"http://java.sun.com/xml/ns/" //$NON-NLS-1$ + "portlet/portlet-app_2_0.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:" //$NON-NLS-1$ + "schemaLocation=\"http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/" //$NON-NLS-1$ + "xml/ns/portlet/portlet-app_2_0.xsd\" version=\"2.0\">\n</portlet-app>"; //$NON-NLS-1$ public PortletDescriptorHelper() { super(); } public PortletDescriptorHelper( IProject project ) { super( project ); } protected void addDescriptorOperations() { addDescriptorOperation ( new RemoveSampleElementsOperation() { @Override public IStatus removeSampleElements() { return doRemoveAllPortlets(); }; } ); addDescriptorOperation ( new AddNewPortletOperation() { @Override public IStatus addNewPortlet( final IDataModel model ) { IStatus status = Status.OK_STATUS; if( canAddNewPortlet( model ) ) { final IFile descriptorFile = getDescriptorFile(); if( descriptorFile != null ) { DOMModelOperation domModelOperation = new DOMModelEditOperation( descriptorFile ) { protected void createDefaultFile() { createDefaultDescriptor( DESCRIPTOR_TEMPLATE, "" ); //$NON-NLS-1$ } protected IStatus doExecute( IDOMDocument document ) { return doAddNewPortlet( document, model ); } }; status = domModelOperation.execute(); } } return status; } } ); addDescriptorOperation ( new RemoveAllPortletsOperation() { @Override public IStatus removeAllPortlets() { return doRemoveAllPortlets(); } } ); } public IStatus addResourceBundle( final String resourceBundle, final String portletName ) { final IFile descriptorFile = getDescriptorFile(); DOMModelOperation operation = new DOMModelEditOperation( descriptorFile ) { @Override protected IStatus doExecute( IDOMDocument document ) { return doAddResourceBundle( document, resourceBundle, portletName ); } }; return operation.execute(); } public boolean canAddNewPortlet( IDataModel model ) { return model.getID().contains( "NewPortlet" ); } public IStatus configurePortletXml( final String newPortletName ) { final IFile descriptorFile = getDescriptorFile(); final IStatus status = new DOMModelEditOperation( descriptorFile ) { protected IStatus doExecute( IDOMDocument document ) { final Element rootElement = document.getDocumentElement(); final NodeList portletNodes = rootElement.getElementsByTagName( "portlet" ); if( portletNodes.getLength() > 0 ) { final Element lastPortletElement = (Element) portletNodes.item( portletNodes.getLength() - 1 ); final Element portletName = NodeUtil.findChildElement( lastPortletElement, "portlet-name" ); portletName.replaceChild( document.createTextNode( newPortletName ), portletName.getFirstChild() ); } return Status.OK_STATUS; } }.execute(); return status; } public IStatus doAddNewPortlet( IDOMDocument document, IDataModel model ) { // <portlet-app> element Element rootElement = document.getDocumentElement(); // new <portlet> element Element newPortletElement = document.createElement( "portlet" ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletElement, "portlet-name", model.getStringProperty( PORTLET_NAME ) ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletElement, "display-name", model.getStringProperty( DISPLAY_NAME ) ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletElement, "portlet-class", getPortletClassText( model ) ); //$NON-NLS-1$ // add <init-param> elements as needed List<ParamValue> initParams = (List<ParamValue>) model.getProperty( INIT_PARAMS ); for( ParamValue initParam : initParams ) { Element newInitParamElement = NodeUtil.appendChildElement( newPortletElement, "init-param" ); //$NON-NLS-1$ NodeUtil.appendChildElement( newInitParamElement, "name", initParam.getName() ); //$NON-NLS-1$ NodeUtil.appendChildElement( newInitParamElement, "value", initParam.getValue() ); //$NON-NLS-1$ } // expiration cache NodeUtil.appendChildElement( newPortletElement, "expiration-cache", "0" ); //$NON-NLS-1$ //$NON-NLS-2$ // supports node Element newSupportsElement = NodeUtil.appendChildElement( newPortletElement, "supports" ); //$NON-NLS-1$ NodeUtil.appendChildElement( newSupportsElement, "mime-type", "text/html" ); //$NON-NLS-1$ //$NON-NLS-2$ // for all support modes need to add into for( String portletMode : ALL_PORTLET_MODES ) { if( model.getBooleanProperty( portletMode ) ) { NodeUtil.appendChildElement( newSupportsElement, "portlet-mode", //$NON-NLS-1$ model.getPropertyDescriptor( portletMode ).getPropertyDescription() ); } } if( model.getBooleanProperty( CREATE_RESOURCE_BUNDLE_FILE ) ) { // need to remove .properties off the end of the bundle_file_path String bundlePath = model.getStringProperty( CREATE_RESOURCE_BUNDLE_FILE_PATH ); String bundleValue = bundlePath.replaceAll( "\\.properties$", StringPool.EMPTY ); //$NON-NLS-1$ String validBuildValue = bundleValue.replaceAll( "\\/", "." ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletElement, "resource-bundle", validBuildValue ); //$NON-NLS-1$ } // add portlet-info Element newPortletInfoElement = NodeUtil.appendChildElement( newPortletElement, "portlet-info" ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletInfoElement, "title", model.getStringProperty( TITLE ) ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletInfoElement, "short-title", model.getStringProperty( SHORT_TITLE ) ); //$NON-NLS-1$ NodeUtil.appendChildElement( newPortletInfoElement, "keywords", model.getStringProperty( KEYWORDS ) ); //$NON-NLS-1$ // security role refs for( String roleName : DEFAULT_SECURITY_ROLE_NAMES ) { NodeUtil.appendChildElement( NodeUtil.appendChildElement( newPortletElement, "security-role-ref" ), "role-name", roleName ); //$NON-NLS-1$ //$NON-NLS-2$ } // check for event-definition elements Node refNode = null; String[] refElementNames = new String[] { "custom-portlet-mode", "custom-window-state", "user-attribute", "security-constraint", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "resource-bundle", "filter", "filter-mapping", "default-namespace", "event-definition", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "public-render-parameter", "listener", "container-runtime-option" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ for( int i = 0; i < refElementNames.length; i++ ) { refNode = NodeUtil.findFirstChild( rootElement, refElementNames[i] ); if( refNode != null ) { break; } } rootElement.insertBefore( newPortletElement, refNode ); // append a newline text node rootElement.appendChild( document.createTextNode( System.getProperty( "line.separator" ) ) ); //$NON-NLS-1$ // format the new node added to the model; FormatProcessorXML processor = new FormatProcessorXML(); processor.formatNode( newPortletElement ); return Status.OK_STATUS; } protected IStatus doAddResourceBundle( IDOMDocument document, String resourceBundle, String portletName ) { final FormatProcessorXML processor = new FormatProcessorXML(); final NodeList portletNameList = document.getElementsByTagName( "portlet-name" ); if( ( portletNameList != null ) && ( portletNameList.getLength() > 0 ) && !CoreUtil.isNullOrEmpty( resourceBundle ) ) { Node portletNameNode = null; for( int i = 0; i < portletNameList.getLength(); i++ ) { if( NodeUtil.getTextContent( portletNameList.item( i ) ).equals( portletName ) ) { portletNameNode = portletNameList.item( i ); } } if( portletNameNode == null ) { return Status.CANCEL_STATUS; } Element newResourceBundleElement = null; Node portlet = portletNameNode.getParentNode(); Node refNode = null; Node supports = NodeUtil.findLastChild( (Element) portlet, "supports" ); if( supports != null ) { Node supportedLocale = NodeUtil.findLastChild( (Element) portlet, "supported-locale" ); if( supportedLocale != null ) { refNode = supportedLocale; } else { refNode = supports; } } else { return Status.CANCEL_STATUS; } newResourceBundleElement = NodeUtil.insertChildElementAfter( (Element) portlet, refNode, "resource-bundle", resourceBundle ); processor.formatNode( newResourceBundleElement ); } return Status.OK_STATUS; } public IStatus doRemoveAllPortlets() { final String portletTagName = "portlet"; DOMModelEditOperation domModelOperation = new DOMModelEditOperation( getDescriptorFile() ) { protected IStatus doExecute( IDOMDocument document ) { return removeAllElements( document, portletTagName ); } }; IStatus status = domModelOperation.execute(); return status; } public String[] getAllPortletNames() { final List<String> allPortletNames = new ArrayList<String>(); final IFile descriptorFile = getDescriptorFile(); if( descriptorFile != null ) { DOMModelOperation op = new DOMModelReadOperation( descriptorFile ) { protected IStatus doExecute( IDOMDocument document ) { NodeList nodeList = document.getElementsByTagName( "portlet-name" ); //$NON-NLS-1$ for( int i = 0; i < nodeList.getLength(); i++ ) { Element portletName = (Element) nodeList.item( i ); allPortletNames.add( NodeUtil.getTextContent( portletName ) ); } return Status.OK_STATUS; } }; op.execute(); } return allPortletNames.toArray( new String[0] ); } public String[] getAllResourceBundles() { final List<String> allResourceBundles = new ArrayList<String>(); final IFile descriptorFile = getDescriptorFile(); if( descriptorFile != null ) { DOMModelOperation op = new DOMModelReadOperation( descriptorFile ) { protected IStatus doExecute( IDOMDocument document ) { NodeList nodeList = document.getElementsByTagName( "resource-bundle" ); //$NON-NLS-1$ for( int i = 0; i < nodeList.getLength(); i++ ) { Element resourceBundle = (Element) nodeList.item( i ); allResourceBundles.add( NodeUtil.getTextContent( resourceBundle ) ); } return Status.OK_STATUS; } }; op.execute(); } return allResourceBundles.toArray( new String[0] ); } public IFile getDescriptorFile() { return super.getDescriptorFile( DESCRIPTOR_FILE ); } protected String getPortletClassText( IDataModel model ) { return model.getStringProperty( QUALIFIED_CLASS_NAME ); } }