Java tutorial
package org.seasar.kvasir.plust; import static org.seasar.kvasir.base.Globals.PROP_SYSTEM_DEVELOPEDPLUGIN_ADDITIONALJARS; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.net.URLDecoder; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidArtifactRTException; import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException; import org.apache.maven.embedder.ContainerCustomizer; import org.apache.maven.embedder.MavenEmbedder; import org.apache.maven.embedder.MavenEmbedderException; import org.apache.maven.model.Build; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.texteditor.MarkerUtilities; import org.maven.ide.eclipse.MavenPlugin; import org.maven.ide.eclipse.core.MavenConsole; import org.maven.ide.eclipse.core.MavenLogger; import org.maven.ide.eclipse.embedder.MavenEmbedderManager; import org.maven.ide.eclipse.embedder.MavenRuntimeManager; import org.maven.ide.eclipse.internal.embedder.MavenEmbeddedRuntime; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.seasar.kvasir.base.plugin.descriptor.PluginDescriptor; import org.seasar.kvasir.base.util.XOMUtils; import org.seasar.kvasir.maven.plugin.ArtifactNotFoundException; import org.seasar.kvasir.maven.plugin.ArtifactPattern; import org.seasar.kvasir.maven.plugin.KvasirPluginUtils; import org.seasar.kvasir.plust.builder.GatherArtifactsTask; import org.seasar.kvasir.plust.maven.MavenEmbedderCallback; import org.seasar.kvasir.plust.maven.internal.KvasirConsole; import freemarker.cache.URLTemplateLoader; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import freemarker.template.Template; import freemarker.template.TemplateException; import net.skirnir.xom.IllegalSyntaxException; import net.skirnir.xom.ValidationException; /** * The main plugin class to be used in the desktop. */ public class KvasirPlugin extends AbstractUIPlugin { public static final String PLUGIN_ID = "org.seasar.kvasir.plust"; public static final String NATURE_ID = PLUGIN_ID + ".kvasirNature"; public static final String BUILDER_ID = PLUGIN_ID + ".kvasirBuilder"; public static final String POM_MARKER_ID = PLUGIN_ID + ".pomMarker"; public static final String LICENSES_PATH = "licenses"; public static final String PROP_TESTENVIRONMENTGROUPID = "testEnvironmentGroupId"; public static final String PROP_TESTENVIRONMENTARTIFACTID = "testEnvironmentArtifactId"; public static final String PROP_TESTENVIRONMENTVERSION = "testEnvironmentVersion"; public static final String PROP_PLUGINVERSION = "pluginVersion"; public static final String IMG_VERTICAL = "icons/th_vertical.gif"; public static final String IMG_HORIZONTAL = "icons/th_horizontal.gif"; public static final String IMG_EXTENSION = "icons/extension_obj.gif"; public static final String IMG_LOGO = "icons/logo.jpg"; public static final String MANIFEST_PATH = "/src/main/plugin/plugin.xml"; public static final String IMG_DECORATION = "icons/kvasir-decoration.gif"; public static final String IMG_REQUIRED = "icons/required-plugin.gif"; public static final String IMG_LIBRARY = "icons/runtime-path.gif"; public static final String IMG_EXTENSION_POINT = "icons/extension-point.gif"; public static final String IMG_ELEMENT = "icons/xom-element.gif"; public static final String PLUGIN_OUTER_LIBRARIES_TAG = "<pluginOuterLibraries>"; //The shared instance. private static KvasirPlugin plugin; private MavenEmbedderManager embedderManager_; private MavenRuntimeManager runtimeManager_; private MavenConsole console_; private Set<String> sourceCheckedArtifactIdSet_ = new HashSet<String>(); private ImageRegistry imageRegistry_; private Map<IProject, IKvasirProject> projectCache_ = new HashMap<IProject, IKvasirProject>(); /** * The constructor. */ public KvasirPlugin() { plugin = this; } /** * This method is called upon plug-in activation */ public void start(BundleContext context) throws Exception { super.start(context); imageRegistry_ = getImageRegistry(); imageRegistry_.put(IMG_REQUIRED, getImageDescriptor(IMG_REQUIRED)); imageRegistry_.put(IMG_LIBRARY, getImageDescriptor(IMG_LIBRARY)); imageRegistry_.put(IMG_EXTENSION_POINT, getImageDescriptor(IMG_EXTENSION_POINT)); imageRegistry_.put(IMG_EXTENSION, getImageDescriptor(IMG_EXTENSION)); imageRegistry_.put(IMG_ELEMENT, getImageDescriptor(IMG_ELEMENT)); MavenLogger.setLog(getLog()); try { console_ = new KvasirConsole(MavenPlugin.getImageDescriptor("icons/kvasir.gif")); //$NON-NLS-1$ } catch (RuntimeException ex) { MavenLogger .log(new Status(IStatus.ERROR, PLUGIN_ID, -1, "Unable to start console: " + ex.toString(), ex)); } runtimeManager_ = new MavenRuntimeManager(getPreferenceStore()); embedderManager_ = new MavenEmbedderManager(console_, runtimeManager_); runtimeManager_.setEmbeddedRuntime(new MavenEmbeddedRuntime(context)); } /** * This method is called when the plug-in is stopped */ public void stop(BundleContext context) throws Exception { super.stop(context); if (embedderManager_ != null) { embedderManager_.shutdown(); } if (console_ != null) { console_.shutdown(); } plugin = null; } /** * Returns the shared instance. */ public static KvasirPlugin getDefault() { return plugin; } /** * Returns an image descriptor for the image file at the given * plug-in relative path. * * @param path the path * @return the image descriptor */ public static ImageDescriptor getImageDescriptor(String path) { return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path); } protected void initializeImageRegistry(ImageRegistry reg) { super.initializeImageRegistry(reg); } public static IStatus constructStatus(Throwable t) { return constructStatus(t.getMessage(), t); } public static IStatus constructStatus(String message) { return constructStatus(message, null); } public static IStatus constructStatus(String message, Throwable t) { return new Status(IStatus.ERROR, KvasirPlugin.PLUGIN_ID, 0, message, t); } public static void mkdirs(IResource container, IProgressMonitor monitor) throws CoreException { if (container.getType() != IResource.FOLDER) { return; } IFolder folder = (IFolder) container; if (!folder.exists()) { mkdirs(folder.getParent(), monitor); folder.create(false, true, new SubProgressMonitor(monitor, 1)); } } public static boolean shouldResourceBeIgnored(String path) { if (path.endsWith("/")) { path = path.substring(0, path.length() - 1); } String name; int slash = path.lastIndexOf('/'); if (slash >= 0) { name = path.substring(slash + 1); } else { name = path; } return name.equalsIgnoreCase(".svn") || name.equalsIgnoreCase("_svn") || name.equalsIgnoreCase("CVS") || name.equalsIgnoreCase("_DELETEME"); } public static void copy(IResource source, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Copying resources", IProgressMonitor.UNKNOWN); try { copy0(source, destination, force, monitor); } finally { monitor.done(); } } static void copy0(IResource source, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { if (shouldResourceBeIgnored(source.getName())) { return; } IResource destinationResource = ResourcesPlugin.getWorkspace().getRoot().findMember(destination); if (source.getType() == IResource.FILE) { if (destinationResource != null && destinationResource.getType() == IResource.FILE) { IFile destinationFile = ResourcesPlugin.getWorkspace().getRoot().getFile(destination); destinationFile.setContents(((IFile) source).getContents(), false, false, new SubProgressMonitor(monitor, 1)); } else { if (destinationResource != null) { destinationResource.delete(false, new SubProgressMonitor(monitor, 1)); } IFile destinationFile = ResourcesPlugin.getWorkspace().getRoot().getFile(destination); mkdirs(destinationFile.getParent(), new SubProgressMonitor(monitor, 1)); source.copy(destination, false, new SubProgressMonitor(monitor, 1)); } } else if (source.getType() == IResource.FOLDER) { IFolder destinationFolder = null; if (destinationResource != null) { if (destinationResource.getType() == IResource.FOLDER) { destinationFolder = (IFolder) destinationResource; } else { destinationResource.delete(false, new SubProgressMonitor(monitor, 1)); } } if (destinationFolder == null) { destinationFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(destination); mkdirs(destinationFolder, new SubProgressMonitor(monitor, 1)); } IResource[] members = ((IFolder) source).members(); for (int i = 0; i < members.length; i++) { copy0(members[i], destination.append(members[i].getName()), false, monitor); } } else { throw new CoreException(constructStatus("Can't copy resource " + source + " to " + destination)); } } public void log(IStatus status) { getLog().log(status); } public void log(String message, Throwable t) { getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, 0, message, t)); } public void log(Throwable t) { String message = t.getMessage(); if (message == null) { message = ""; } getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, 0, message, t)); } public MavenConsole getConsole() { return console_; } public MavenProject getMavenProject(IFile pomFile, IProgressMonitor monitor) { if (monitor == null) { monitor = new NullProgressMonitor(); } return (MavenProject) executeInEmbedder(new ReadProjectTask(pomFile), monitor); } public Artifact[] gatherArtifacts(IFile pomFile, IProgressMonitor monitor) { if (monitor == null) { monitor = new NullProgressMonitor(); } return (Artifact[]) executeInEmbedder(new GatherArtifactsTask(pomFile), monitor); } @SuppressWarnings("unchecked") public void resolveClasspathEntries(Set<IClasspathEntry> libraryEntries, Set<String> moduleArtifacts, IFile pomFile, boolean recursive, boolean downloadSources, IProgressMonitor monitor) { monitor.beginTask("Reading " + pomFile.getLocation(), IProgressMonitor.UNKNOWN); try { if (monitor.isCanceled()) { throw new OperationCanceledException(); } final MavenProject mavenProject = getMavenProject(pomFile, new SubProgressMonitor(monitor, 1)); if (mavenProject == null) { return; } deleteMarkers(pomFile); // TODO use version? moduleArtifacts.add(mavenProject.getGroupId() + ":" + mavenProject.getArtifactId()); Set artifacts = mavenProject.getArtifacts(); for (Iterator it = artifacts.iterator(); it.hasNext();) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } final Artifact a = (Artifact) it.next(); monitor.subTask("Processing " + a.getId()); if (!"jar".equals(a.getType())) { continue; } // TODO use version? if (!moduleArtifacts.contains(a.getGroupId() + ":" + a.getArtifactId()) && // TODO verify if there is an Eclipse API to check that archive is acceptable ("jar".equals(a.getType()) || "zip".equals(a.getType()))) { String artifactLocation = a.getFile().getAbsolutePath(); // TODO add a lookup through workspace projects Path srcPath = null; File srcFile = new File( artifactLocation.substring(0, artifactLocation.length() - 4) + "-sources.jar"); if (srcFile.exists()) { // XXX ugly hack to do not download any sources srcPath = new Path(srcFile.getAbsolutePath()); } else if (downloadSources && !isSourceChecked(a)) { srcPath = (Path) executeInEmbedder(new MavenEmbedderCallback() { public Object run(MavenEmbedder mavenEmbedder, IProgressMonitor monitor) { monitor.beginTask("Resolve sources " + a.getId(), IProgressMonitor.UNKNOWN); try { Artifact src = mavenEmbedder.createArtifactWithClassifier(a.getGroupId(), a.getArtifactId(), a.getVersion(), "java-source", "sources"); if (src != null) { mavenEmbedder.resolve(src, mavenProject.getRemoteArtifactRepositories(), mavenEmbedder.getLocalRepository()); return new Path(src.getFile().getAbsolutePath()); } } catch (AbstractArtifactResolutionException ex) { String name = ex.getGroupId() + ":" + ex.getArtifactId() + "-" + ex.getVersion() + "." + ex.getType(); getConsole().logMessage(ex.getOriginalMessage() + " " + name); } finally { monitor.done(); } return null; } }, new SubProgressMonitor(monitor, 1)); setSourceChecked(a); } libraryEntries.add(JavaCore.newLibraryEntry(new Path(artifactLocation), srcPath, null)); } } if (recursive) { IContainer parent = pomFile.getParent(); List modules = mavenProject.getModules(); for (Iterator it = modules.iterator(); it.hasNext() && !monitor.isCanceled();) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } String module = (String) it.next(); IResource memberPom = parent.findMember(module + "/" + IKvasirProject.POM_FILE_NAME); if (memberPom != null && memberPom.getType() == IResource.FILE) { resolveClasspathEntries(libraryEntries, moduleArtifacts, (IFile) memberPom, true, downloadSources, new SubProgressMonitor(monitor, 1)); } } } } catch (OperationCanceledException ex) { throw ex; } catch (InvalidArtifactRTException ex) { addMarker(pomFile, ex.getBaseMessage(), 1, IMarker.SEVERITY_ERROR); } catch (Throwable ex) { addMarker(pomFile, ex.toString(), 1, IMarker.SEVERITY_ERROR); } finally { monitor.done(); } } public boolean isSourceChecked(Artifact artifact) { return sourceCheckedArtifactIdSet_.contains(artifact.getId()); } public void setSourceChecked(Artifact artifact) { sourceCheckedArtifactIdSet_.add(artifact.getId()); } public void resetSourceCheckedSet() { sourceCheckedArtifactIdSet_.clear(); } public void addMarker(IResource file, String message, int lineNumber, int severity) { try { deleteMarkers(file); // TODO Workaround if (message.indexOf("Duplicate project ID found") >= 0) { return; } IMarker marker = file.createMarker(POM_MARKER_ID); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); if (lineNumber == -1) { lineNumber = 1; } marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); } catch (CoreException ex) { log(ex); } } public void deleteMarkers(IResource file) { try { file.deleteMarkers(POM_MARKER_ID, false, IResource.DEPTH_ZERO); } catch (CoreException ex) { log(ex); } } public Object executeInEmbedder(MavenEmbedderCallback template, IProgressMonitor monitor) { MavenEmbedder embedder = getMavenEmbedder(); try { return template.run(embedder, monitor); } finally { try { embedder.stop(); } catch (MavenEmbedderException ex) { MavenLogger.log(new Status(IStatus.ERROR, PLUGIN_ID, -1, "Unable to stop MavenEmbedder", ex)); } } } public Object executeInEmbedder(String name, MavenEmbedderCallback template) { MavenEmbedder embedder = getMavenEmbedder(); try { EmbedderJob job = new EmbedderJob(name, template, embedder); job.schedule(); try { job.join(); // TODO check job.getResult() return job.getCallbackResult(); } catch (InterruptedException ex) { getConsole().logError("Interrupted " + ex.toString()); return null; } } finally { try { embedder.stop(); } catch (MavenEmbedderException ex) { MavenLogger.log(new Status(IStatus.ERROR, PLUGIN_ID, -1, "Unable to stop MavenEmbedder", ex)); } } } private synchronized MavenEmbedder getMavenEmbedder() { try { return embedderManager_.createEmbedder(new ContainerCustomizer() { public void customize(PlexusContainer container) { } }); } catch (CoreException ex) { MavenLogger.log(new Status(IStatus.ERROR, PLUGIN_ID, -1, "Cannot create MavenEmbedder", ex)); throw new RuntimeException(ex); } } @SuppressWarnings("unchecked") public void unzip(File zipArchive, IFolder destination, boolean forceOverwite, IProgressMonitor monitor) throws CoreException { if (!forceOverwite && destination.exists()) { return; } monitor.beginTask("Unzipping", IProgressMonitor.UNKNOWN); try { ZipFile zipFile = null; try { zipFile = new ZipFile(zipArchive); for (Enumeration enm = zipFile.entries(); enm.hasMoreElements();) { monitor.worked(1); if (monitor.isCanceled()) { throw new OperationCanceledException(); } ZipEntry entry = (ZipEntry) enm.nextElement(); if (entry.isDirectory()) { mkdirs(destination.getFolder(entry.getName()), new SubProgressMonitor(monitor, 1)); } else { IFile file = destination.getFile(entry.getName()); if (file.exists()) { file.setContents(zipFile.getInputStream(entry), false, false, new SubProgressMonitor(monitor, 1)); } else { mkdirs(file.getParent(), new SubProgressMonitor(monitor, 1)); file.create(zipFile.getInputStream(entry), false, new SubProgressMonitor(monitor, 1)); } } } } catch (ZipException ex) { throw new CoreException(constructStatus(ex)); } catch (IOException ex) { throw new CoreException(constructStatus(ex)); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException ex) { log(ex); } } } } finally { monitor.done(); } } public Properties loadBuildProperties(IProject project) throws CoreException { Properties prop = loadProperties(project.getFile("build.properties")); prop.setProperty("projectRoot", project.getLocation().toOSString()); //$NON-NLS-1$ return prop; } public Properties loadProperties(IFile file) throws CoreException { Properties prop = new Properties(); if (file.exists()) { InputStream is = null; try { is = file.getContents(); prop.load(is); } catch (IOException ex) { throw new CoreException(constructStatus("Can't load build.properties", ex)); } finally { if (is != null) { try { is.close(); } catch (IOException ex) { log("Can't close input stream: " + file, ex); } } } } return prop; } public void storeBuildProperties(IProject project, Properties prop) throws CoreException { storeProperties(prop, project.getFile("build.properties")); } public void storeProperties(Properties prop, IFile file) throws CoreException { File outputFile = file.getLocation().toFile(); OutputStream os = null; try { os = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(os); prop.store(bos, null); bos.flush(); bos.close(); os = null; file.refreshLocal(IResource.DEPTH_ZERO, null); } catch (IOException ex) { throw new CoreException(KvasirPlugin.constructStatus("Can't output " + file, ex)); } finally { if (os != null) { try { os.close(); } catch (IOException ex) { plugin.getLog().log(KvasirPlugin.constructStatus("Can't close output stream", ex)); } } } } public void createInstanceFromArchetype(IProject project, boolean forBuilding, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Creating instance from archetype", IProgressMonitor.UNKNOWN); try { Properties root = loadBuildProperties(project); String archetypeId = root.getProperty("archetypeId"); if (archetypeId == null) { return; } final Bundle bundle = getBundle(); String archetypePath = "archetypes/" + archetypeId + "/"; Configuration cfg = new Configuration(); cfg.setEncoding(Locale.getDefault(), "UTF-8"); cfg.setTemplateLoader(new URLTemplateLoader() { protected URL getURL(String path) { return bundle.getEntry(path); } }); cfg.setObjectWrapper(new DefaultObjectWrapper()); evaluateTemplate(archetypePath, "", forBuilding, project.getProjectRelativePath(), project, cfg, bundle, root, archetypeId, new SubProgressMonitor(monitor, 1)); } finally { monitor.done(); } } @SuppressWarnings("unchecked") void evaluateTemplate(String templateRootPath, String templateRelativePath, boolean forBuilding, IPath location, IProject project, Configuration cfg, final Bundle bundle, Properties prop, String archetypeId, IProgressMonitor monitor) throws CoreException { String targetPath = templateRootPath + templateRelativePath; for (Enumeration enm = bundle.getEntryPaths(targetPath); enm != null && enm.hasMoreElements();) { String path = (String) enm.nextElement(); String relativePath = path.substring(templateRootPath.length()); if (("build/webapp/".startsWith(relativePath) || relativePath.startsWith("build/webapp/")) ^ forBuilding) { continue; } if (shouldResourceBeIgnored(path.substring(targetPath.length()))) { continue; } StringWriter sw = new StringWriter(); try { new Template("pathName", new StringReader(URLDecoder.decode(relativePath, "UTF-8")), cfg) .process(prop, sw); } catch (IOException ex) { throw new CoreException(KvasirPlugin.constructStatus( "Can't process template '" + path + "' in archetype '" + archetypeId + "'", ex)); } catch (TemplateException ex) { throw new CoreException(KvasirPlugin.constructStatus( "Can't process template '" + path + "' in archetype '" + archetypeId + "'", ex)); } IPath theLocation = location.append(sw.toString()); if (path.endsWith("/")) { KvasirPlugin.mkdirs(project.getFolder(theLocation), new SubProgressMonitor(monitor, 1)); evaluateTemplate(templateRootPath, relativePath, forBuilding, location, project, cfg, bundle, prop, archetypeId, monitor); } else { InputStream in; if (shouldEvaluateAsTemplate(path)) { byte[] evaluated; try { sw = new StringWriter(); cfg.getTemplate(path).process(prop, sw); evaluated = sw.toString().getBytes("UTF-8"); } catch (TemplateException ex) { throw new CoreException(KvasirPlugin.constructStatus( "Can't process template '" + path + "' in archetype '" + archetypeId + "'", ex)); } catch (IOException ex) { throw new CoreException(KvasirPlugin.constructStatus( "Can't process template '" + path + "' in archetype '" + archetypeId + "'", ex)); } in = new ByteArrayInputStream(evaluated); } else { try { in = bundle.getEntry(path).openStream(); } catch (IOException ex) { throw new CoreException(KvasirPlugin.constructStatus( "Can't process template '" + path + "' in archetype '" + archetypeId + "'", ex)); } } try { IFile outputFile = project.getFile(theLocation); if (outputFile.exists()) { outputFile.setContents(in, false, false, new SubProgressMonitor(monitor, 1)); } else { KvasirPlugin.mkdirs(outputFile.getParent(), new SubProgressMonitor(monitor, 1)); outputFile.create(in, false, new SubProgressMonitor(monitor, 1)); } } finally { try { in.close(); } catch (IOException ignore) { } } } } } boolean shouldEvaluateAsTemplate(String path) { return !(path.endsWith(".gif") || path.endsWith(".jpg") || path.endsWith(".png") || path.endsWith(".pdf") || path.endsWith(".zip") || path.endsWith(".tar") || path.endsWith(".gz") || path.endsWith(".jar") || path.endsWith(".war") || path.endsWith(".ear")); } public static String getString(String key) { if (getDefault() == null) { // FIXME null???????????? return key; } return Platform.getResourceString(getDefault().getBundle(), "%" + key); } public KvasirProject getKvasirProject(IEditorInput input) { IProject project = getCurrentProject(input); if (!projectCache_.containsKey(project)) { createKvasirProject(project); } return (KvasirProject) projectCache_.get(project); } public KvasirProject getKvasirProject(IProject project) { Object object = projectCache_.get(project); if (object instanceof KvasirProject) { return (KvasirProject) object; } return createKvasirProject(project); } private KvasirProject createKvasirProject(IProject project) { IJavaProject javaProject = JavaCore.create(project); KvasirProject kvasirProject = new KvasirProject(javaProject); projectCache_.put(project, kvasirProject); return kvasirProject; } public void flushKvasirProject(IEditorInput input) { IProject project = getCurrentProject(input); projectCache_.remove(project); } public IProject getCurrentProject(IEditorInput input) { IFileEditorInput editorInput = (IFileEditorInput) input; return editorInput.getFile().getProject(); } public Image getImage(String key) { return imageRegistry_.get(key); } public String getIndexDir() { return new File(getStateLocation().toFile(), "index").getAbsolutePath(); } public void cleanTestEnvironment(IProject project, boolean cleanConfiguration, IProgressMonitor monitor) { monitor.beginTask("Cleaning test environment", 3); try { IFolder target = project.getFolder(IKvasirProject.BUILD_PATH); if (!target.exists()) { target.create(false, true, new SubProgressMonitor(monitor, 1)); } else { target.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1)); cleanTestFolder(project, cleanConfiguration, target, new SubProgressMonitor(monitor, 1)); } } catch (CoreException ex) { log("Failure to cleanTestEnvironment", ex); } finally { monitor.done(); } } void cleanTestFolder(IProject project, boolean cleanConfiguration, IFolder folder, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Cleaning folder", IProgressMonitor.UNKNOWN); try { Set<IPath> exclusiveSet = new HashSet<IPath>(); if (!cleanConfiguration) { IFolder configuration = project.getFolder(IKvasirProject.TEST_CONFIGURATION_PATH); if (configuration != null) { exclusiveSet.add(configuration.getFullPath()); } IFolder rtwork = project.getFolder(IKvasirProject.TEST_RTWORK_PATH); if (rtwork != null) { exclusiveSet.add(rtwork.getFullPath()); } } IJavaProject javaProject = JavaCore.create(project); exclusiveSet.add(javaProject.getOutputLocation()); IClasspathEntry[] entries = javaProject.getRawClasspath(); for (int i = 0; i < entries.length; i++) { IPath outputLocation = entries[i].getOutputLocation(); if (outputLocation != null) { exclusiveSet.add(outputLocation); } } cleanFolder(folder, exclusiveSet, monitor); } finally { monitor.done(); } } boolean cleanFolder(IFolder folder, Set<IPath> exclusiveSet, IProgressMonitor monitor) throws CoreException { boolean cleared = true; IResource[] members = folder.members(); for (int i = 0; i < members.length; i++) { boolean clearEntry = true; if (exclusiveSet.contains(members[i].getFullPath())) { cleared = false; continue; } if (members[i].getType() == IResource.FOLDER) { clearEntry = cleanFolder((IFolder) members[i], exclusiveSet, monitor); } if (clearEntry) { members[i].delete(false, new SubProgressMonitor(monitor, 1)); } else { cleared = false; } } return cleared; } public void buildTestEnvironment(IProject project, IProgressMonitor monitor) { monitor.beginTask("Building test environment", 140); try { Properties prop = loadBuildProperties(project); String testEnvironmentGroupId = prop.getProperty(PROP_TESTENVIRONMENTGROUPID); if (testEnvironmentGroupId == null) { testEnvironmentGroupId = getString("NewPluginWizardSecondPage.DEFAULT_TEST_ENVIRONMENT_GROUPID"); } String testEnvironmentArtifactId = prop.getProperty(PROP_TESTENVIRONMENTARTIFACTID); if (testEnvironmentArtifactId == null) { testEnvironmentArtifactId = getString( "NewPluginWizardSecondPage.DEFAULT_TEST_ENVIRONMENT_ARTIFACTID"); } String testEnvironmentVersion = prop.getProperty(PROP_TESTENVIRONMENTVERSION); if (testEnvironmentVersion == null) { // ????????????????? return; } buildTestEnvironment(project, testEnvironmentGroupId, testEnvironmentArtifactId, testEnvironmentVersion, monitor); monitor.worked(100); Artifact[] artifacts = gatherArtifacts(project.getFile(IKvasirProject.POM_FILE_NAME), monitor); monitor.worked(10); deployRequiredPluginsToTestEnvironment(project, artifacts, monitor); monitor.worked(10); deployStaticResources(project, prop.getProperty("archetypeId"), monitor); monitor.worked(10); updateOuterLibrariesProperties(project, artifacts, monitor); monitor.worked(10); } catch (CoreException ex) { log("Can' execute prepareTestEnvironment", ex); } finally { monitor.done(); } } void buildTestEnvironment(IProject project, String groupId, String artifactId, String version, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Preparing test environment", 80); try { MavenProject mavenProject = plugin.getMavenProject(project.getFile(IKvasirProject.POM_FILE_NAME), monitor); monitor.worked(10); Artifact distArchive = (Artifact) plugin.executeInEmbedder( new PrepareTestEnvironmentTask(mavenProject, groupId, artifactId, version), monitor); monitor.worked(10); if (distArchive == null) { plugin.getConsole().logError("Can't resolve archive: " + distArchive); throw new CoreException(KvasirPlugin.constructStatus("Can't resolve archive: " + distArchive)); } ZipFile zipFile = null; File file = null; try { zipFile = new ZipFile(distArchive.getFile()); ZipEntry entry = zipFile .getEntry(distArchive.getArtifactId() + "-" + distArchive.getVersion() + "/kvasir.war"); if (entry == null) { throw new CoreException(KvasirPlugin.constructStatus( "Can't find kvasir.war in " + distArchive.getFile().getAbsolutePath())); } file = File.createTempFile("kvasir", ".tmp"); file.deleteOnExit(); copyZipEntryAsFile(zipFile, entry, file); IFolder webapp = project.getFolder(IKvasirProject.WEBAPP_PATH); unzip(file, webapp, true, monitor); monitor.worked(50); webapp.setDerived(true); monitor.worked(10); } catch (ZipException ex) { throw new CoreException(KvasirPlugin.constructStatus(ex)); } catch (IOException ex) { throw new CoreException(KvasirPlugin.constructStatus(ex)); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException ex) { plugin.log(ex); } zipFile = null; } if (file != null) { file.delete(); } } // ??distribution???????? // ?????????? String targetPluginDirectoryName = mavenProject.getArtifactId() + "-" + mavenProject.getArtifact().getVersion(); IFolder targetPluginDirectory = project .getFolder(IKvasirProject.TEST_PLUGINS_PATH + "/" + targetPluginDirectoryName); if (targetPluginDirectory.exists()) { targetPluginDirectory.delete(false, new SubProgressMonitor(monitor, 1)); } } finally { monitor.done(); } } void copyZipEntryAsFile(ZipFile zipFile, ZipEntry entry, File file) { InputStream is = null; OutputStream os = null; try { is = zipFile.getInputStream(entry); os = new FileOutputStream(file); BufferedInputStream bis = new BufferedInputStream(is); BufferedOutputStream bos = new BufferedOutputStream(os); byte[] buf = new byte[4096]; int len; while ((len = bis.read(buf)) >= 0) { bos.write(buf, 0, len); } bis.close(); is = null; bos.close(); os = null; } catch (IOException ex) { if (is != null) { try { is.close(); } catch (IOException ex2) { KvasirPlugin.getDefault().log(ex2); } } if (os != null) { try { os.close(); } catch (IOException ex2) { KvasirPlugin.getDefault().log(ex2); } } } } void deployStaticResources(IProject project, String archetypeId, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Deploying static resources", IProgressMonitor.UNKNOWN); try { if (archetypeId == null) { return; } createInstanceFromArchetype(project, true, new SubProgressMonitor(monitor, 1)); if (monitor.isCanceled()) { throw new OperationCanceledException(); } } finally { monitor.done(); } } public void deployRequiredPluginsToTestEnvironment(IProject project, Artifact[] artifacts, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Deploying required plugins", 1); try { if (artifacts == null) { return; } IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1); subMonitor.beginTask("Gathering required plugins", artifacts.length); try { IFolder destinationFolder = project.getFolder(IKvasirProject.TEST_PLUGINS_PATH); for (int i = 0; i < artifacts.length; i++) { subMonitor.worked(1); if (!KvasirPluginUtils.isPluginArtifact(artifacts[i])) { continue; } unzip(artifacts[i].getFile(), destinationFolder, true, new SubProgressMonitor(monitor, 1)); } } finally { subMonitor.done(); } } finally { monitor.done(); } } public void updateOuterLibrariesProperties(IProject project, Artifact[] artifacts, IProgressMonitor monitor) throws CoreException { monitor.beginTask("Updating outerLibraries' information", IProgressMonitor.UNKNOWN); IFile pomFile = null; try { Properties prop = new Properties(); do { if (artifacts == null) { break; } pomFile = project.getFile(IKvasirProject.POM_FILE_NAME); if (!pomFile.exists()) { pomFile = null; break; } KvasirPlugin.getDefault().deleteMarkers(pomFile); MavenProject pom = getMavenProject(pomFile, monitor); if (pom == null) { break; } Build build = pom.getBuild(); if (build == null) { break; } Plugin plugin = (Plugin) build.getPluginsAsMap() .get("org.seasar.kvasir.maven.plugin:maven-kvasir-plugin"); if (plugin == null) { break; } Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration(); Xpp3Dom[] children = configuration.getChildren(); String outerLibraries = null; for (int i = 0; i < children.length; i++) { if ("pluginOuterLibraries".equals(children[i].getName())) { outerLibraries = children[i].getValue(); break; } } if (outerLibraries == null) { break; } prop = KvasirPluginUtils.getOuterLibrariesProperties(null, outerLibraries, new HashSet<Artifact>(Arrays.asList(artifacts))); } while (false); storeProperties(prop, project.getFile(IKvasirProject.OUTERLIBRARIES_FILE_PATH)); IFile custom = project.getFile(IKvasirProject.CUSTOM_XPROPERTIES_FILE_PATH); Properties customProp = loadProperties(custom); String value = prop.getProperty("outerLibraries"); if (value != null) { customProp.setProperty(PROP_SYSTEM_DEVELOPEDPLUGIN_ADDITIONALJARS, value); } else { customProp.remove(PROP_SYSTEM_DEVELOPEDPLUGIN_ADDITIONALJARS); } storeProperties(customProp, custom); } catch (IOException ex) { KvasirPlugin.getDefault().log("Can't update outerLibraries' information", ex); } catch (ArtifactNotFoundException ex) { if (pomFile != null) { ArtifactPattern[] patterns = ex.getArtifactPatterns(); if (patterns != null) { for (int i = 0; i < patterns.length; i++) { createMarker(pomFile, patterns[i].toString()); } } else { createMarker(pomFile, null); } } } finally { monitor.done(); } } private void createMarker(IFile file, String pattern) throws CoreException { Map<String, Integer> attributes = new HashMap<String, Integer>(); attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); String message; if (pattern == null) { message = "Outer library cannot be resolved"; } else { message = "Outer library '" + pattern + "' cannot be resolved"; } MarkerUtilities.setMessage(attributes, message); int lineNumber = getLineNumber(file, PLUGIN_OUTER_LIBRARIES_TAG); if (lineNumber != -1) { MarkerUtilities.setLineNumber(attributes, lineNumber); } if (pattern != null) { String pomContent = null; InputStream in = null; try { in = file.getContents(); BufferedReader br = new BufferedReader(new InputStreamReader(in, file.getCharset())); StringWriter sw = new StringWriter(); char[] buf = new char[4096]; int len; while ((len = br.read(buf)) != -1) { sw.write(buf, 0, len); } pomContent = sw.toString(); } catch (IOException ex) { ; } catch (CoreException ex) { ; } finally { if (in != null) { try { in.close(); } catch (IOException ex) { ; } } } if (pomContent != null) { // TODO This implementation may be a bit incorrect. int idx = pomContent.indexOf(PLUGIN_OUTER_LIBRARIES_TAG); if (idx != -1) { int pre = idx + PLUGIN_OUTER_LIBRARIES_TAG.length(); int i; for (i = pre; i < pomContent.length(); i++) { char ch = pomContent.charAt(i); if (ch == ',' || ch == '<') { if (setPositionIfMatched(pomContent, pre, i, pattern, attributes)) { break; } if (ch == '<') { break; } pre = i + 1; } } if (i == pomContent.length()) { setPositionIfMatched(pomContent, pre, pomContent.length(), pattern, attributes); } } } } MarkerUtilities.createMarker(file, attributes, KvasirPlugin.POM_MARKER_ID); } @SuppressWarnings("unchecked") private boolean setPositionIfMatched(String string, int start, int end, String pattern, Map attributes) { String tkn = string.substring(start, end); int left = getLeftSpaceLength(tkn); int right = getRightSpaceLength(tkn); if (pattern.equals(tkn.substring(left, tkn.length() - right))) { MarkerUtilities.setCharStart(attributes, start + left); MarkerUtilities.setCharEnd(attributes, end - right); return true; } else { return false; } } private int getLeftSpaceLength(String tkn) { for (int i = 0; i < tkn.length(); i++) { char ch = tkn.charAt(i); if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { return i; } } return tkn.length(); } private int getRightSpaceLength(String tkn) { for (int i = tkn.length() - 1; i >= 0; i--) { char ch = tkn.charAt(i); if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { return (tkn.length() - 1 - i); } } return tkn.length(); } private int getLineNumber(IFile file, String pattern) throws CoreException { InputStream in = null; try { in = file.getContents(); BufferedReader br = new BufferedReader(new InputStreamReader(in, file.getCharset())); String line; int lineNumber = 1; while ((line = br.readLine()) != null) { int idx = line.indexOf(pattern); if (idx != -1) { return lineNumber; } lineNumber++; } return -1; } catch (IOException ex) { return -1; } catch (CoreException ex) { return -1; } finally { if (in != null) { try { in.close(); } catch (IOException ex) { ; } } } } public PluginDescriptor loadPluginDescriptor(IProject project) throws ValidationException, IllegalSyntaxException, IOException { IFile pluginFile = project.getFile(IKvasirProject.PLUGIN_FILE_PATH); if (!pluginFile.exists()) { return null; } return XOMUtils.toBean( new BufferedReader( new InputStreamReader(new FileInputStream(pluginFile.getLocation().toFile()), "UTF-8")), PluginDescriptor.class); } public MavenEmbedderManager getMavenEmbedderManager() { return embedderManager_; } }