Java tutorial
/******************************************************************************* * Copyright 2011 Google Inc. All Rights Reserved. * * 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 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package com.google.gdt.eclipse.designer.actions.deploy; import com.google.common.collect.Lists; import com.google.gdt.eclipse.designer.actions.AbstractModuleAction; import com.google.gdt.eclipse.designer.common.Constants; import com.google.gdt.eclipse.designer.launch.GwtLaunchConfigurationDelegate; import com.google.gdt.eclipse.designer.model.module.ModuleElement; import com.google.gdt.eclipse.designer.model.module.ServletElement; import com.google.gdt.eclipse.designer.model.web.WebUtils; import com.google.gdt.eclipse.designer.util.ModuleVisitor; import com.google.gdt.eclipse.designer.util.Utils; import com.google.gdt.eclipse.designer.wizards.Activator; import org.eclipse.wb.internal.core.DesignerPlugin; import org.eclipse.wb.internal.core.utils.IOUtils2; import org.eclipse.wb.internal.core.utils.Version; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.window.Window; import org.apache.commons.lang.StringUtils; import java.io.ByteArrayInputStream; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * Action for deployment selected GWT module into application server. * * @author scheglov_ke * @coverage gwt.deploy */ public class DeployModuleAction extends AbstractModuleAction { //////////////////////////////////////////////////////////////////////////// // // Action implementation // //////////////////////////////////////////////////////////////////////////// @Override protected void selectedModuleChanged(IAction action) { if (m_selectedModule != null) { action.setEnabled(true); action.setToolTipText("Deploy module '" + m_selectedModule.getId() + "' on application server"); } else { action.setEnabled(false); action.setToolTipText("No selected GWT module to deploy"); } } @Override protected void runWithSelectedModule() throws Exception { final DeployDialog deployDialog = new DeployDialog(DesignerPlugin.getShell(), Activator.getDefault(), m_selectedModule); if (deployDialog.open() != Window.OK) { return; } // IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { monitor.beginTask("Deployment of module '" + m_selectedModule.getId() + "'", 1); // create script { monitor.worked(1); createBuildScript(deployDialog); } // execute script { IProject project = m_selectedModule.getProject(); IFolder targetFolder = m_selectedModule.getModuleFolder(); File buildFile = targetFolder.getFile("build.xml").getLocation().toFile(); AntHelper antHelper = new AntHelper(buildFile, project.getLocation().toFile()); antHelper.execute(monitor); } } catch (Throwable e) { throw new InvocationTargetException(e); } } }; ProgressMonitorDialog progressMonitorDialog = new ProgressMonitorDialog(DesignerPlugin.getShell()); progressMonitorDialog.run(true, false, runnableWithProgress); } //////////////////////////////////////////////////////////////////////////// // // ANT Script // //////////////////////////////////////////////////////////////////////////// /** * Creates build.xml file in same folder as module. */ private void createBuildScript(DeployDialog deployDialog) throws Exception { String moduleId = m_selectedModule.getId(); // IProject project = m_selectedModule.getProject(); IFolder targetFolder = m_selectedModule.getModuleFolder(); // prepare script String script = getScriptTemplate(); // apply template values script = StringUtils.replace(script, "##GWT_HOME##", Utils.getGWTLocation(project)); script = StringUtils.replace(script, "##PROJECT_ROOT##", project.getLocation().toOSString()); script = StringUtils.replace(script, "##MODULE_ID##", moduleId); script = StringUtils.replace(script, "##WAR_NAME##", deployDialog.getWarName()); script = StringUtils.replace(script, "##DEPLOY_DIR##", deployDialog.getServerPath()); script = StringUtils.replace(script, "##COMPILER_STYLE##", deployDialog.getCompilerStyle()); script = StringUtils.replace(script, "##COMPILER_MAX_MEMORY##", deployDialog.getCompilerMaxMemory()); // set class path elements { String classpathElements = ""; String[] classpath = getGWTProjectClasspath(project); for (int i = 0; i < classpath.length; i++) { String element = classpath[i].replace('\\', '/'); classpathElements += "\t\t\t\t<pathelement location=\"" + element + "\" />"; if (i != classpath.length - 1) { classpathElements += "\n"; } } script = StringUtils.replace(script, "##CLASS_PATH_ELEMENTS##", classpathElements); } // set servlets { final StringBuffer buffer = new StringBuffer(); ModuleVisitor.accept(m_selectedModule, new ModuleVisitor() { @Override public void endVisitModule(ModuleElement module) { List<ServletElement> servletElements = module.getServletElements(); for (ServletElement servletElement : servletElements) { String servletName = servletElement.getClassName(); { buffer.append("\t<servlet>\n"); buffer.append("\t\t<servlet-name>" + servletName + "</servlet-name>\n"); buffer.append( "\t\t<servlet-class>" + servletElement.getClassName() + "</servlet-class>\n"); buffer.append("\t</servlet>\n"); } { buffer.append("\t<servlet-mapping>\n"); buffer.append("\t\t<servlet-name>" + servletName + "</servlet-name>\n"); buffer.append("\t\t<url-pattern>" + servletElement.getPath() + "</url-pattern>\n"); buffer.append("\t</servlet-mapping>\n"); } } } }); // apply sevlets script = StringUtils.replace(script, "##SERVLETS##", buffer.toString()); } // create/copy jar's { String targetModulePath = WebUtils.getWebFolderName(project); String jarsScript = prepareJars(project, targetModulePath, true); jarsScript = StringUtils.chomp(jarsScript, "\n"); script = StringUtils.replace(script, "<!--##PROJECT_AND_REQUIRED_JARS##-->", jarsScript); } // create build.xml IFile buildFile = targetFolder.getFile("build.xml"); ByteArrayInputStream source = new ByteArrayInputStream(script.getBytes()); if (buildFile.exists()) { buildFile.setContents(source, true, true, null); } else { buildFile.create(source, true, null); } } private String getScriptTemplate() throws Exception { IProject project = m_selectedModule.getProject(); String buildVersion = getBuildVersion(project).getStringMajorMinor(); String scriptName = "build-" + buildVersion + ".xml"; // try to find script near to module { IFile scriptFile = m_selectedModule.getModuleFolder().getFile(new Path(scriptName)); if (scriptFile.exists()) { return IOUtils2.readString(scriptFile); } } // OK, load default script return IOUtils2.readString(DeployModuleAction.class.getResourceAsStream(scriptName)); } /** * @return the version of build file, not exactly same as version of GWT. */ private static Version getBuildVersion(IProject project) { Version version = Utils.getVersion(project); if (version.isHigherOrSame(Utils.GWT_2_0)) { version = Utils.GWT_2_0; } return version; } //////////////////////////////////////////////////////////////////////////// // // Script: jars // //////////////////////////////////////////////////////////////////////////// /** * Returns ANT code for creating jar's for given project itself, coping its jar's from classpath * and calls itself for required projects. */ private static String prepareJars(IProject project, String targetModulePath, boolean addRuntimeJars) throws Exception { String script = ""; // IJavaProject javaProject = JavaCore.create(project); IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots(); // add <jar> task for creating jar from project source and output folders { List<String> sourceLocations = Lists.newArrayList(); List<String> binaryLocations = Lists.newArrayList(); for (IPackageFragmentRoot packageFragmentRoot : roots) { if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) { // add source location sourceLocations.add(packageFragmentRoot.getResource().getLocation().toPortableString()); // add output location { // prepare output location IPath location; { IClasspathEntry cpEntry = packageFragmentRoot.getRawClasspathEntry(); location = cpEntry.getOutputLocation(); if (location == null) { location = javaProject.getOutputLocation(); } } // add absolute location { // remove first segment (project) location = location.removeFirstSegments(1); // prepare absolute location IPath absoluteLocation = project.getLocation().append(location); binaryLocations.add(absoluteLocation.toPortableString()); } } } } // script += "\t\t<!--=== " + project.getName() + " ===-->\n"; script += "\t\t<jar destfile='" + targetModulePath + "/WEB-INF/lib/" + project.getName() + ".jar'>\n"; script += prepareFileSets(sourceLocations, "**"); script += prepareFileSets(binaryLocations, "**/*.class"); script += "\t\t</jar>\n"; } // add <copy> task for coping required runtime jar's if (addRuntimeJars) { String jars = ""; IRuntimeClasspathEntry[] classpathEntries = JavaRuntime.computeUnresolvedRuntimeClasspath(javaProject); for (int entryIndex = 0; entryIndex < classpathEntries.length; entryIndex++) { IRuntimeClasspathEntry entry = classpathEntries[entryIndex]; IRuntimeClasspathEntry[] resolvedEntries = JavaRuntime.resolveRuntimeClasspathEntry(entry, javaProject); for (int resolvedEntryIndex = 0; resolvedEntryIndex < resolvedEntries.length; resolvedEntryIndex++) { IRuntimeClasspathEntry resolvedEntry = resolvedEntries[resolvedEntryIndex]; if (resolvedEntry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES && resolvedEntry.getType() == IRuntimeClasspathEntry.ARCHIVE) { String location = resolvedEntry.getLocation(); // exclude gwt-user.jar, it is in classpath, but it has Servlet class, so can not be in application if (location.endsWith("gwt-user.jar")) { continue; } // add jar file in fileset jars += "\t\t\t<fileset file=\"" + location + "\"/>\n"; } } } // if (jars.length() != 0) { script += "\t\t<copy todir='" + targetModulePath + "/WEB-INF/lib'>\n"; script += jars; script += "\t\t</copy>\n"; } } // add required projects { IProject[] referencedProjects = project.getReferencedProjects(); for (int i = 0; i < referencedProjects.length; i++) { IProject referencedProject = referencedProjects[i]; script += prepareJars(referencedProject, targetModulePath, false); } } // return script; } /** * Prepares source of <fileset>/<include> for given list of directories and inclusion pattern. */ private static String prepareFileSets(List<String> dirs, String includePattern) { String result = ""; for (String dir : dirs) { result += "\t\t\t<fileset dir=\"" + dir + "\">\n"; result += "\t\t\t\t<include name=\"" + includePattern + "\"/>\n"; result += "\t\t\t</fileset>\n"; } return result; } //////////////////////////////////////////////////////////////////////////// // // Classpath // //////////////////////////////////////////////////////////////////////////// /** * @return GWT runtime classpath for given {@link IProject}. */ public static String[] getGWTProjectClasspath(IProject project) throws CoreException { // create new launch configuration just as container for parameters, we are not going to save it ILaunchConfigurationWorkingCopy launchConfiguration; { ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); ILaunchConfigurationType launchConfigurationType = launchManager .getLaunchConfigurationType(Constants.LAUNCH_TYPE_ID_SHELL); launchConfiguration = launchConfigurationType.newInstance(null, "__GWTDesigner_tmp"); } // set project name launchConfiguration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName()); // create delegate just for asking classpath GwtLaunchConfigurationDelegate delegate = new GwtLaunchConfigurationDelegate(); return delegate.getClasspathAll(launchConfiguration); } }