/******************************************************************************* * Copyright (c) 2003, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - Initial API and implementation * Greg Amerson <gregory.amerson@liferay.com> *******************************************************************************/ package com.liferay.ide.server.tomcat.core; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.project.core.util.ProjectUtil; import com.liferay.ide.server.core.ILiferayServerBehavior; import com.liferay.ide.server.tomcat.core.util.LiferayTomcatUtil; import com.liferay.ide.server.util.LiferayPublishHelper; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jst.server.tomcat.core.internal.Messages; import org.eclipse.jst.server.tomcat.core.internal.TomcatPlugin; import org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour; import org.eclipse.jst.server.tomcat.core.internal.xml.Factory; import org.eclipse.jst.server.tomcat.core.internal.xml.XMLUtil; import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context; import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Server; import org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance; import org.eclipse.osgi.util.NLS; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.IServer; import org.eclipse.wst.server.core.model.IModuleResource; import org.eclipse.wst.server.core.model.IModuleResourceDelta; import org.eclipse.wst.server.core.model.ServerBehaviourDelegate; import org.w3c.dom.Document; /** * @author gregory.amerson@liferay.com * @author Simon Jiang */ @SuppressWarnings( { "restriction", "rawtypes" } ) public class LiferayTomcatServerBehavior extends TomcatServerBehaviour implements ILiferayServerBehavior { private List<IModule[]> redeployModules; public LiferayTomcatServerBehavior() { super(); } @Override protected MultiStatus executePublishers( int kind, List<IModule[]> modules, List<Integer> deltaKinds, IProgressMonitor monitor, IAdaptable info ) throws CoreException { return super.executePublishers( kind, ( redeployModules == null ) ? modules : redeployModules, deltaKinds, monitor, info ); } public IPath getDeployedPath( IModule[] module ) { return getModuleDeployDirectory( module[0] ); } @Override public IPath getModuleDeployDirectory( IModule module ) { final IPath defaultPath = super.getModuleDeployDirectory( module ); IPath updatedPath = null; if( defaultPath != null && defaultPath.lastSegment() != null ) { final IProject project = module.getProject(); final String requiredSuffix = ProjectUtil.getRequiredSuffix( project ); if( requiredSuffix != null && ! defaultPath.lastSegment().endsWith( requiredSuffix ) ) { String lastSegment = defaultPath.lastSegment(); updatedPath = defaultPath.removeLastSegments( 1 ).append( lastSegment + requiredSuffix ); } } return updatedPath == null ? defaultPath : updatedPath; } public LiferayTomcatServer getLiferayTomcatServer() { return (LiferayTomcatServer) getServer().loadAdapter( LiferayTomcatServer.class, null ); } public IModuleResourceDelta[] getPublishedResourceDelta( IModule[] module ) { return super.getPublishedResourceDelta( module ); } public IModuleResource[] getResources( IModule[] module ) { return super.getResources( module ); } public List<IModule[]> getRedeployModules() { return redeployModules; } @Override public String[] getRuntimeVMArguments() { return super.getRuntimeVMArguments(); } public IStatus moveContextToAutoDeployDir( IModule module, IPath deployDir, IPath baseDir, IPath autoDeployDir, boolean noPath, boolean serverStopped ) { IPath confDir = baseDir.append( "conf" ); //$NON-NLS-1$ IPath serverXml = confDir.append( "server.xml" ); //$NON-NLS-1$ try { Factory factory = new Factory(); factory.setPackageName( "org.eclipse.jst.server.tomcat.core.internal.xml.server40" ); //$NON-NLS-1$ Server publishedServer = (Server) factory.loadDocument( new FileInputStream( serverXml.toFile() ) ); ServerInstance publishedInstance = new ServerInstance( publishedServer, null, null ); IPath contextPath = null; if( autoDeployDir.isAbsolute() ) { contextPath = autoDeployDir; } else { contextPath = baseDir.append( autoDeployDir ); } File contextDir = contextPath.toFile(); if( !contextDir.exists() ) { contextDir.mkdirs(); } Context context = publishedInstance.createContext( -1 ); context.setReloadable( "true" ); //$NON-NLS-1$ final String moduleName = module.getName(); final String requiredSuffix = ProjectUtil.getRequiredSuffix( module.getProject() ); String contextName = moduleName; if( ! moduleName.endsWith( requiredSuffix ) ) { contextName = moduleName + requiredSuffix; } context.setSource( "org.eclipse.jst.jee.server:" + contextName ); //$NON-NLS-1$ if( Boolean.valueOf( context.getAttributeValue( "antiResourceLocking" ) ).booleanValue() ) //$NON-NLS-1$ { context.setAttributeValue( "antiResourceLocking", "false" ); //$NON-NLS-1$ //$NON-NLS-2$ } File contextFile = new File( contextDir, contextName + ".xml" ); //$NON-NLS-1$ if( !LiferayTomcatUtil.isExtProjectContext( context ) ) { // If requested, remove path attribute if( noPath ) { context.removeAttribute( "path" ); //$NON-NLS-1$ } // need to fix the doc base to contain entire path to help autoDeployer for Liferay context.setDocBase( deployDir.toOSString() ); // context.setAttributeValue("antiJARLocking", "true"); // check to see if we need to move from conf folder // IPath existingContextPath = confDir.append("Catalina/localhost").append(contextFile.getName()); // if (existingContextPath.toFile().exists()) { // existingContextPath.toFile().delete(); // } DocumentBuilder builder = XMLUtil.getDocumentBuilder(); Document contextDoc = builder.newDocument(); contextDoc.appendChild( contextDoc.importNode( context.getElementNode(), true ) ); XMLUtil.save( contextFile.getAbsolutePath(), contextDoc ); } } catch( Exception e ) { // Trace.trace(Trace.SEVERE, // "Could not modify context configurations to serve directly for Tomcat configuration " + // confDir.toOSString() + ": " + e.getMessage()); return new Status( IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind( Messages.errorPublishConfiguration, new String[] { e.getLocalizedMessage() } ), e ); } finally { // monitor.done(); } return Status.OK_STATUS; } public ILiferayTomcatConfiguration getLiferayTomcatConfiguration() throws CoreException { return getLiferayTomcatServer().getLiferayTomcatConfiguration(); } @Override protected void publishFinish( IProgressMonitor monitor ) throws CoreException { super.publishFinish( monitor ); this.redeployModules = null; } @Override protected void publishModule( int kind, int deltaKind, IModule[] moduleTree, IProgressMonitor monitor ) throws CoreException { boolean shouldPublishModule = LiferayPublishHelper.prePublishModule( this, kind, deltaKind, moduleTree, getPublishedResourceDelta( moduleTree ), monitor ); if( shouldPublishModule ) { if( getServer().getServerState() != IServer.STATE_STOPPED ) { if( deltaKind == ServerBehaviourDelegate.ADDED || deltaKind == ServerBehaviourDelegate.REMOVED ) { setServerRestartState( true ); } } setModulePublishState( moduleTree, IServer.PUBLISH_STATE_NONE ); } else { // wasn't able to publish module, should set to needs full publish setModulePublishState( moduleTree, IServer.PUBLISH_STATE_FULL ); } } @Override protected void publishModules( int kind, List modules, List deltaKind2, MultiStatus multi, IProgressMonitor monitor ) { super.publishModules( kind, ( redeployModules == null ) ? modules : redeployModules, deltaKind2, multi, monitor ); } public void redeployModule( IModule[] module ) throws CoreException { setModulePublishState( module, IServer.PUBLISH_STATE_FULL ); IAdaptable info = new IAdaptable() { @SuppressWarnings( "unchecked" ) public Object getAdapter( Class adapter ) { if( String.class.equals( adapter ) ) { return "user"; //$NON-NLS-1$ } return null; } }; final List<IModule[]> modules = new ArrayList<IModule[]>(); modules.add( module ); redeployModules = modules; try { publish( IServer.PUBLISH_FULL, modules, null, info ); } catch( CoreException e ) { throw e; } finally { redeployModules = null; } } @Override public void setupLaunchConfiguration( ILaunchConfigurationWorkingCopy workingCopy, IProgressMonitor monitor ) throws CoreException { super.setupLaunchConfiguration( workingCopy, monitor ); workingCopy.setAttribute( DebugPlugin.ATTR_CONSOLE_ENCODING, "UTF-8" ); //$NON-NLS-1$ String existingVMArgs = workingCopy.getAttribute( IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (String) null ); if( null != existingVMArgs ) { String[] parsedVMArgs = DebugPlugin.parseArguments( existingVMArgs ); List<String> memoryArgs = new ArrayList<String>(); if( !CoreUtil.isNullOrEmpty( parsedVMArgs ) ) { for( String pArg : parsedVMArgs ) { if( pArg.startsWith( "-Xm" ) || pArg.startsWith( "-XX:" ) ) //$NON-NLS-1$ //$NON-NLS-2$ { memoryArgs.add( pArg ); } } } String argsWithoutMem = mergeArguments( existingVMArgs, getRuntimeVMArguments(), memoryArgs.toArray( new String[0] ), false ); String fixedArgs = mergeArguments( argsWithoutMem, getRuntimeVMArguments(), null, false ); workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, fixedArgs ); } } }