diff options
17 files changed, 1531 insertions, 25 deletions
diff --git a/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF b/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF index 994cdd27..f5ace57a 100644 --- a/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF @@ -28,4 +28,5 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.4 Export-Package: org.eclipse.releng.tools, org.eclipse.releng.tools.git;x-friends:="org.eclipse.releng.tests", + org.eclipse.releng.tools.pomversion, org.eclipse.releng.tools.preferences diff --git a/bundles/org.eclipse.releng.tools/plugin.properties b/bundles/org.eclipse.releng.tools/plugin.properties index b1d30a5e..92208bc8 100644 --- a/bundles/org.eclipse.releng.tools/plugin.properties +++ b/bundles/org.eclipse.releng.tools/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2007 IBM Corporation and others. +# Copyright (c) 2003, 2013 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 @@ -16,3 +16,17 @@ RelEng=RelEng Tools RelEngActionSet.description=RelEng Tool Action Set RelEngActionSet.Release=Releasing... RelEngActionSet.tooltip=Release Projects + +releaseAction.label = Re&lease... +releasedAction.label = Released +compareProjectsAction.tooltip = Compare the selected project(s) with the released versions +replaceProjectsAction.tooltip = Replace the selcted project(s) with the released versions +loadMapProjectsAction.label = Load Map Projects +tagMapProjectsAction.label = Tag Map Projects +fixCopyrightsAction.label = Fix Copyrights +copyrightToolPrefPage.name = Copyright Tool +relengMapProjectPrefPage.name = Releng Map Project Selection +pomPrefPage.name = POM Version Tool +pomVersionMarker.name = POM Version Problem +pomVersionMarkerCategory.name = POM Version Problems +action.label = Release...
\ No newline at end of file diff --git a/bundles/org.eclipse.releng.tools/plugin.xml b/bundles/org.eclipse.releng.tools/plugin.xml index 66fd3125..11b640ef 100644 --- a/bundles/org.eclipse.releng.tools/plugin.xml +++ b/bundles/org.eclipse.releng.tools/plugin.xml @@ -14,22 +14,22 @@ value="org.eclipse.team.core.repository=org.eclipse.team.cvs.core.cvsnature"> </filter> <action - label="Re&lease..." + label="%releaseAction.label" class="org.eclipse.releng.tools.TagAndReleaseAction" menubarPath="team.main/group2" id="org.eclipse.releng.tools.tagAndRelease"> </action> <action - label="Released" - tooltip="Compare the selected project(s) with the released versions" + label="%releasedAction.label" + tooltip="%compareProjectsAction.tooltip" class="org.eclipse.releng.tools.CompareLocalToMap" menubarPath="compareWithMenu/compareWithGroup" id="org.eclipse.releng.tools.compareWithReleased"> </action> <action - label="Released" + label="%releasedAction.label" class="org.eclipse.releng.tools.ReplaceLocalFromMap" - tooltip="Replace the selcted project(s) with the released versions" + tooltip="%replaceProjectsAction.tooltip" menubarPath="replaceWithMenu/replaceWithGroup" id="org.eclipse.releng.tools.replaceWithReleased"> </action> @@ -39,27 +39,27 @@ objectClass="org.eclipse.ui.IWorkingSet" id="org.eclipse.releng.tools.WorkingSetContributions"> <action - label="Release..." + label="%action.label" class="org.eclipse.releng.tools.TagAndReleaseAction" menubarPath="team.main/group2" id="org.eclipse.releng.tools.tagAndRelease"> </action> <action - label="Released" - tooltip="Compare the selected project(s) with the released versions" + label="%releasedAction.label" + tooltip="%compareProjectsAction.tooltip" class="org.eclipse.releng.tools.CompareLocalToMap" menubarPath="compareWithMenu/compareWithGroup" id="org.eclipse.releng.tools.compareWithReleased"> </action> <action - label="Released" + label="%releasedAction.label" class="org.eclipse.releng.tools.ReplaceLocalFromMap" - tooltip="Replace the selcted project(s) with the released versions" + tooltip="%replaceProjectsAction.tooltip" menubarPath="replaceWithMenu/replaceWithGroup" id="org.eclipse.releng.tools.replaceWithReleased"> </action> <action - label="Fix Copyrights" + label="%fixCopyrightsAction.label" class="org.eclipse.releng.tools.AdvancedFixCopyrightAction" menubarPath="additions" enablesFor="+" @@ -72,13 +72,13 @@ nameFilter="*.map" id="org.eclipse.releng.cvs.mapActions"> <action - label="Load Map Projects" + label="%loadMapProjectsAction.label" class="org.eclipse.releng.tools.LoadMap" menubarPath="team.main/group1" id="org.eclipse.releng.cvs.LoadMap"> </action> <action - label="Tag Map Projects" + label="%tagMapProjectsAction.label" class="org.eclipse.releng.tools.TagMap" menubarPath="team.main/group1" id="org.eclipse.releng.cvs.TagMap"> @@ -89,7 +89,7 @@ objectClass="org.eclipse.core.resources.IResource" id="org.eclipse.releng.internal.tools.AdvancedCopyrightContribution"> <action - label="Fix Copyrights" + label="%fixCopyrightsAction.label" class="org.eclipse.releng.tools.AdvancedFixCopyrightAction" menubarPath="additions" enablesFor="+" @@ -119,16 +119,21 @@ <!-- ********** Preference Pages ************** --> <extension point="org.eclipse.ui.preferencePages"> <page - name="Copyright Tool" + name="%copyrightToolPrefPage.name" class="org.eclipse.releng.tools.preferences.CopyrightPreferencePage" id="org.eclipse.releng.tools.preferences.CopyrightPreferencePage"> </page> <page class="org.eclipse.releng.tools.preferences.MapProjectPreferencePage" id="org.eclipse.releng.tools.preferences.MapProjectPreferencePage" - name="Releng Map Project Selection" + name="%relengMapProjectPrefPage.name" category="org.eclipse.team.ui.TeamPreferences"> </page> + <page + class="org.eclipse.releng.tools.preferences.PomVersionPreferencePage" + id="org.eclipse.releng.tools.preferences.PomVersionPreferencePage" + name="%pomPrefPage.name"> + </page> </extension> @@ -153,5 +158,32 @@ </adapter> </factory> </extension> +<extension id="pomVersionProblem" point="org.eclipse.core.resources.markers" name="%pomVersionMarker.name"> + <super type="org.eclipse.core.resources.problemmarker"/> + <super type="org.eclipse.core.resources.textmarker"/> + <persistent value="true"/> +</extension> + <extension + point="org.eclipse.ui.ide.markerSupport"> + <markerTypeCategory + name="%pomVersionMarkerCategory.name"> + <markerTypeReference + id="org.eclipse.releng.tools.pomVersionProblem"> + </markerTypeReference> + </markerTypeCategory> + </extension> + <extension + point="org.eclipse.ui.ide.markerResolution"> + <markerResolutionGenerator + class="org.eclipse.releng.tools.pomversion.PomVersionResolutionGenerator" + markerType="org.eclipse.releng.tools.pomVersionProblem"> + </markerResolutionGenerator> + </extension> + <extension + point="org.eclipse.ui.startup"> + <startup + class="org.eclipse.releng.tools.pomversion.RelEngPluginEarlyStartup"> + </startup> + </extension> </plugin> diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java index d7176c64..9f5211b6 100644 --- a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 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 @@ -13,14 +13,24 @@ package org.eclipse.releng.tools; import java.util.MissingResourceException; import java.util.ResourceBundle; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; +import org.osgi.framework.BundleContext; + +import org.eclipse.releng.tools.pomversion.IPomVersionConstants; +import org.eclipse.releng.tools.pomversion.PomVersionErrorReporter; +import org.eclipse.team.core.RepositoryProvider; + import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.team.core.RepositoryProvider; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; + import org.eclipse.ui.plugin.AbstractUIPlugin; @@ -39,7 +49,9 @@ public class RelEngPlugin extends AbstractUIPlugin { public static final String MAP_FOLDER = Messages.getString("RelEngPlugin.2"); //$NON-NLS-1$ private static final String BINARY_REPOSITORY_PROVIDER_CLASS_NAME= "org.eclipse.pde.internal.core.BinaryRepositoryProvider"; //$NON-NLS-1$ - + private PomVersionErrorReporter fPomReporter = new PomVersionErrorReporter(); + + //The shared instance. private static RelEngPlugin plugin; //Resource bundle. @@ -57,6 +69,33 @@ public class RelEngPlugin extends AbstractUIPlugin { } } + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ID); + if(node != null) { + node.addPreferenceChangeListener(fPomReporter); + String severity = getPreferenceStore().getString(IPomVersionConstants.POM_VERSION_ERROR_LEVEL); + if(!IPomVersionConstants.VALUE_IGNORE.equals(severity)) { + ResourcesPlugin.getWorkspace().addResourceChangeListener(fPomReporter, IResourceChangeEvent.POST_BUILD); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ID); + if(node != null) { + node.removePreferenceChangeListener(fPomReporter); + ResourcesPlugin.getWorkspace().removeResourceChangeListener(fPomReporter); + } + super.stop(context); + } + /** * Returns the shared instance. */ @@ -103,7 +142,16 @@ public class RelEngPlugin extends AbstractUIPlugin { public static void log(int severity, String message, Throwable e) { log(new Status(severity, ID, 0, message, e)); } - + + /** + * Log the given exception as an error. + * + * @param e exception to log + */ + public static void log(Throwable e){ + log(new Status(IStatus.ERROR, ID, 0, e.getMessage(), e)); + } + /** * Log the given status. Do not use this method for the IStatus from a CoreException. * Use<code>log(CoreException)</code> instead so the stack trace is not lost. diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/IPomVersionConstants.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/IPomVersionConstants.java new file mode 100644 index 00000000..a91535aa --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/IPomVersionConstants.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.releng.tools.pomversion; + +import org.eclipse.releng.tools.RelEngPlugin; + + +/** + * Contains all the constants used by the POM version tool. + */ +public interface IPomVersionConstants { + + /** + * The marker type id for POM version problems specified in the markers extension. + * Value is: <code>org.eclipse.releng.tools.pomVersionProblem</code> + */ + public final static String PROBLEM_MARKER_TYPE = RelEngPlugin.ID + ".pomVersionProblem"; //$NON-NLS-1$ + + /** + * String attribute stored in the problem marker for the correct version that should be in the POM file + */ + public static final String POM_CORRECT_VERSION = "pom.CorrectVersion"; //$NON-NLS-1$ + + /** + * Preference setting that stores the severity level for pom version problem markers. + * Preference value must be a string and one of {@link #VALUE_ERROR}, {@link #VALUE_WARNING} or {@link #VALUE_IGNORE}. + */ + public final static String POM_VERSION_ERROR_LEVEL = RelEngPlugin.ID + ".invalidPomVersionErrorLevel"; //$NON-NLS-1$ + + /** + * Constant representing the preference value 'ignore'. + * Value is: <code>Ignore</code> + */ + public static final String VALUE_IGNORE = "Ignore"; //$NON-NLS-1$ + /** + * Constant representing the preference value 'warning'. + * Value is: <code>Warning</code> + */ + public static final String VALUE_WARNING = "Warning"; //$NON-NLS-1$ + /** + * Constant representing the preference value 'error'. + * Value is: <code>Error</code> + */ + public static final String VALUE_ERROR = "Error"; //$NON-NLS-1$ +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/Messages.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/Messages.java new file mode 100644 index 00000000..453c5b3c --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/Messages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.pomversion; + +import org.eclipse.osgi.util.NLS; + + +final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.releng.tools.pomversion.messages"; //$NON-NLS-1$ + + public static String PomVersionErrorReporter_pom_version_error_marker_message; + public static String PomVersionMarkerResolution_label; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + // Do not instantiate + } + +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionErrorReporter.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionErrorReporter.java new file mode 100644 index 00000000..64c9848f --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionErrorReporter.java @@ -0,0 +1,400 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.pomversion; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Stack; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.osgi.framework.Version; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.releng.tools.RelEngPlugin; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.filebuffers.ITextFileBuffer; +import org.eclipse.core.filebuffers.ITextFileBufferManager; +import org.eclipse.core.filebuffers.LocationKind; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + +import org.eclipse.ui.texteditor.MarkerUtilities; + + +/** + * Validates the content of the pom.xml. Currently the only check is that the + * version specified in pom.xml matches the bundle version. + * + */ +public class PomVersionErrorReporter implements IResourceChangeListener, IEclipsePreferences.IPreferenceChangeListener { + + class PomResourceDeltaVisitor implements IResourceDeltaVisitor { + + public boolean visit(IResourceDelta delta) { + if (delta != null) { + IResource resource = delta.getResource(); + switch(resource.getType()) { + case IResource.PROJECT: { + //Should we not care about non-plugin projects? + IProject project = (IProject) resource; + try { + if(project.getDescription().hasNature("org.eclipse.pde.PluginNature")) { //$NON-NLS-1$ + if((delta.getFlags() & IResourceDelta.OPEN) > 0) { + validate(project); + return false; + } + return true; + } + } + catch(CoreException ce) { + RelEngPlugin.log(ce); + } + return false; + } + case IResource.ROOT: + case IResource.FOLDER: { + return true; + } + case IResource.FILE: { + switch(delta.getKind()) { + case IResourceDelta.REMOVED: { + //if manifest removed, clean up markers + if(resource.getProjectRelativePath().equals(MANIFEST_PATH)) { + //manifest content changed + IProject p = resource.getProject(); + if(p.isAccessible()) { + cleanMarkers(p); + } + } + break; + } + case IResourceDelta.ADDED: { + //if the POM or manifest has been added scan them + if(resource.getProjectRelativePath().equals(MANIFEST_PATH) || + resource.getProjectRelativePath().equals(POM_PATH)) { + validate(resource.getProject()); + } + break; + } + case IResourceDelta.CHANGED: { + //if the content has changed clean + scan + if((delta.getFlags() & IResourceDelta.CONTENT) > 0) { + if(resource.getProjectRelativePath().equals(MANIFEST_PATH) || + resource.getProjectRelativePath().equals(POM_PATH)) { + validate(resource.getProject()); + } + } + break; + } + default: { + break; + } + } + return false; + } + } + } + return false; + } + } + + /** + * XML parsing handler to check the POM version infos + */ + class PomVersionHandler extends DefaultHandler { + private Version bundleVersion; + private Stack elements = new Stack(); + private boolean checkVersion = false; + private Locator locator; + IFile pom = null; + String severity = null; + + public PomVersionHandler(IFile file, Version bundleVersion, String pref) { + pom = file; + severity = pref; + this.bundleVersion = bundleVersion; + } + + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (ELEMENT_VERSION.equals(qName)) { + if (!elements.isEmpty() && ELEMENT_PROJECT.equals(elements.peek())) { + checkVersion = true; + } + } + elements.push(qName); + } + + public void endElement(String uri, String localName, String qName) throws SAXException { + elements.pop(); + } + + public void characters(char[] ch, int start, int length) throws SAXException { + if (checkVersion) { + checkVersion = false; + // Compare the versions + String versionString = new String(ch, start, length); + String origVer = versionString; + try { + // Remove snapshot suffix + int index = versionString.indexOf(SNAPSHOT_SUFFIX); + if (index >= 0) { + versionString = versionString.substring(0, index); + } + Version pomVersion = Version.parseVersion(versionString); + // Remove qualifiers and snapshot + Version bundleVersion2 = new Version(bundleVersion.getMajor(), bundleVersion.getMinor(), bundleVersion.getMicro()); + Version pomVersion2 = new Version(pomVersion.getMajor(), pomVersion.getMinor(), pomVersion.getMicro()); + + if (!bundleVersion2.equals(pomVersion2)) { + String correctedVersion = bundleVersion2.toString(); + if (index >= 0) { + correctedVersion = correctedVersion.concat(SNAPSHOT_SUFFIX); + } + + try { + // Need to create a document to calculate the markers charstart and charend + IDocument doc = createDocument(pom); + int lineOffset = doc.getLineOffset(locator.getLineNumber() - 1); // locator lines start at 1 + int linLength = doc.getLineLength(locator.getLineNumber() - 1); + String str = doc.get(lineOffset, linLength); + index = str.indexOf(origVer); + int charStart = lineOffset + index; + int charEnd = charStart + origVer.length(); + reportMarker(NLS.bind(Messages.PomVersionErrorReporter_pom_version_error_marker_message, pomVersion2.toString(), bundleVersion2.toString()), + locator.getLineNumber(), + charStart, + charEnd, + correctedVersion, + pom, + severity); + } catch (BadLocationException e) { + RelEngPlugin.log(e); + } + } + } catch (IllegalArgumentException e) { + // Do nothing, user has a bad version + } + } + } + } + + /** + * Project relative path to the pom.xml file + */ + public static final IPath POM_PATH = new Path("pom.xml"); //$NON-NLS-1$ + + /** + * Project relative path to the manifest file. + */ + public static final IPath MANIFEST_PATH = new Path(JarFile.MANIFEST_NAME); + private static final String ELEMENT_PROJECT = "project"; //$NON-NLS-1$ + private static final String ELEMENT_VERSION = "version"; //$NON-NLS-1$ + private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; //$NON-NLS-1$ + + + /** + * Clean up all markers + * + * @param project + */ + void cleanMarkers(IResource resource) { + try { + resource.deleteMarkers(IPomVersionConstants.PROBLEM_MARKER_TYPE, false, IResource.DEPTH_INFINITE); + } + catch(CoreException e) { + RelEngPlugin.log(e); + } + } + + /** + * Validates the version in the Manifest.MF file against the version in the <code>pom.xml</code> file + * + * @param project + * @param severity + */ + public void validate(IProject project) { + if(project == null || !project.isAccessible()) { + return; + } + //clean up existing markers + cleanMarkers(project); + + String severity = RelEngPlugin.getPlugin().getPreferenceStore().getString(IPomVersionConstants.POM_VERSION_ERROR_LEVEL); + if (IPomVersionConstants.VALUE_IGNORE.equals(severity)) { + return; + } + IFile manifest = project.getFile(MANIFEST_PATH); + if(!manifest.exists()) { + return; + } + IFile pom = project.getFile(POM_PATH); + if(!pom.exists()) { + return; + } + + // Get the manifest version + Version bundleVersion = Version.emptyVersion; + try { + Manifest mani = new Manifest(manifest.getContents()); + java.util.jar.Attributes attributes = mani.getMainAttributes(); + String ver = attributes.getValue("Bundle-Version"); //$NON-NLS-1$ + if(ver == null) { + return; + } + bundleVersion = new Version(ver); + } catch (IOException e) { + RelEngPlugin.log(e); + return; + } catch (CoreException e) { + RelEngPlugin.log(e); + return; + } + // Compare it to the POM file version + try { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + SAXParser parser = parserFactory.newSAXParser(); + PomVersionHandler handler = new PomVersionHandler(pom, bundleVersion, severity); + parser.parse(pom.getContents(), handler); + } catch (Exception e1) { + // Ignored, if there is a problem with the POM file don't create a marker + } + } + + /** + * Creates a new POM version problem marker with the given attributes + * @param message the message for the marker + * @param lineNumber the line number of the problem + * @param charStart the starting character offset + * @param charEnd the ending character offset + * @param correctedVersion the correct version to be inserted + * @param pom the handle to the POM file + * @param severity the severity of the marker to create + */ + void reportMarker(String message, int lineNumber, int charStart, int charEnd, String correctedVersion, IFile pom, String severity) { + try { + HashMap attributes = new HashMap(); + attributes.put(IMarker.MESSAGE, message); + if (severity.equals(IPomVersionConstants.VALUE_WARNING)){ + attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING)); + } else { + attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); + } + if (lineNumber == -1) { + lineNumber = 1; + } + attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber)); + attributes.put(IMarker.CHAR_START, new Integer(charStart)); + attributes.put(IMarker.CHAR_END, new Integer(charEnd)); + attributes.put(IPomVersionConstants.POM_CORRECT_VERSION, correctedVersion); + MarkerUtilities.createMarker(pom, attributes, IPomVersionConstants.PROBLEM_MARKER_TYPE); + } catch (CoreException e){ + RelEngPlugin.log(e); + } + } + + /** + * Creates a new {@link IDocument} for the given {@link IFile}. <code>null</code> + * is returned if the {@link IFile} does not exist or the {@link ITextFileBufferManager} + * cannot be acquired or there was an exception trying to create the {@link IDocument}. + * + * @param file + * @return a new {@link IDocument} or <code>null</code> + */ + protected IDocument createDocument(IFile file) { + if (!file.exists()) { + return null; + } + ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); + if (manager == null) { + return null; + } + try { + manager.connect(file.getFullPath(), LocationKind.NORMALIZE, null); + ITextFileBuffer textBuf = manager.getTextFileBuffer(file.getFullPath(), LocationKind.NORMALIZE); + IDocument document = textBuf.getDocument(); + manager.disconnect(file.getFullPath(), LocationKind.NORMALIZE, null); + return document; + } catch (CoreException e) { + RelEngPlugin.log(e); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent event) { + IResourceDelta delta = event.getDelta(); + if(delta != null) { + final PomResourceDeltaVisitor visitor = new PomResourceDeltaVisitor(); + try { + delta.accept(visitor); + } catch (CoreException e) { + RelEngPlugin.log(e); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) + */ + public void preferenceChange(PreferenceChangeEvent event) { + if(IPomVersionConstants.POM_VERSION_ERROR_LEVEL.equals(event.getKey())) { + final String severity = (String) event.getNewValue(); + if(severity != null) { + if(IPomVersionConstants.VALUE_IGNORE.equals(severity)) { + //we turned it off + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + } + else if(IPomVersionConstants.VALUE_IGNORE.equals(event.getOldValue())) { + // we turned it on + ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD); + } + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject[] projects = root.getProjects(); + for (int i = 0; i < projects.length; i++) { + validate(projects[i]); + } + } + } + } +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionMarkerResolution.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionMarkerResolution.java new file mode 100644 index 00000000..a1b8a3a5 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionMarkerResolution.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.pomversion; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.xml.sax.SAXException; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.releng.tools.RelEngPlugin; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.ui.IMarkerResolution; + + +/** + * Marker resolution for when version in pom.xml does not match the plug-in version. + * Replaces the version string to one based on the version in the manifest. The corrected + * version must have been stored on the marker at creation time. + */ +public class PomVersionMarkerResolution implements IMarkerResolution { + + private static final String ELEMENT_VERSION = "version"; //$NON-NLS-1$ + private String correctedVersion; + + /** + * New marker resolution that will offer to replace the current POM version with corrected version + * @param correctedVersion new version to insert + */ + public PomVersionMarkerResolution(String correctedVersion) { + this.correctedVersion = correctedVersion; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IMarkerResolution#getLabel() + */ + public String getLabel() { + return NLS.bind(Messages.PomVersionMarkerResolution_label, correctedVersion); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IMarkerResolution#run(org.eclipse.core.resources.IMarker) + */ + public void run(IMarker marker) { + if (correctedVersion == null || correctedVersion.trim().length() == 0) { + return; + } + IResource resource = marker.getResource(); + if (resource.exists() && resource.getType() == IResource.FILE) { + IFile file = (IFile) resource; + if (!file.isReadOnly()) { + InputStream fileInput = null; + try { + + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + fileInput = file.getContents(); + Document doc = docBuilder.parse(fileInput); + + Node root = doc.getDocumentElement(); + NodeList list = root.getChildNodes(); + + for (int i = 0; i < list.getLength(); i++) { + Node node = list.item(i); + if (ELEMENT_VERSION.equals(node.getNodeName())) { + // TODO Need to check this method is as robust as setTextContent in 1.5 + node.getFirstChild().setNodeValue(correctedVersion); +// node.setTextContent(correctedVersion); + } + } + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(outputStream); + transformer.transform(source, result); + + IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, null); + if (!status.isOK()) { + throw new CoreException(status); + } + + ByteArrayInputStream stream = new ByteArrayInputStream(outputStream.toByteArray()); + file.setContents(stream, true, false, null); + + } catch (ParserConfigurationException e) { + RelEngPlugin.log(e); + } catch (SAXException e) { + RelEngPlugin.log(e); + } catch (IOException e) { + RelEngPlugin.log(e); + } catch (TransformerException e) { + RelEngPlugin.log(e); + } catch (CoreException e) { + RelEngPlugin.log(e); + } finally { + if (fileInput != null) { + try { + fileInput.close(); + } catch (IOException e) { + } + } + } + + } + + } + } +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionResolutionGenerator.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionResolutionGenerator.java new file mode 100644 index 00000000..4a98b306 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/PomVersionResolutionGenerator.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.pomversion; + +import org.eclipse.releng.tools.RelEngPlugin; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.core.resources.IMarker; + +import org.eclipse.ui.IMarkerResolution; +import org.eclipse.ui.IMarkerResolutionGenerator; + + +public class PomVersionResolutionGenerator implements IMarkerResolutionGenerator { + + private static IMarkerResolution[] NO_RESOLUTIONS = new IMarkerResolution[0]; + + public IMarkerResolution[] getResolutions(IMarker marker) { + try { + if (marker.getType().equals(IPomVersionConstants.PROBLEM_MARKER_TYPE)){ + String correctedVersion = (String) marker.getAttribute(IPomVersionConstants.POM_CORRECT_VERSION); + return new IMarkerResolution[] {new PomVersionMarkerResolution(correctedVersion)}; + } + } catch (CoreException e){ + RelEngPlugin.log(e); + } + return NO_RESOLUTIONS; + } + +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/RelEngPluginEarlyStartup.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/RelEngPluginEarlyStartup.java new file mode 100644 index 00000000..562cfc65 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/RelEngPluginEarlyStartup.java @@ -0,0 +1,23 @@ +/*******************************************************************************
+ * Copyright (c) 2013 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
+ *******************************************************************************/
+package org.eclipse.releng.tools.pomversion;
+
+import org.eclipse.ui.IStartup;
+
+
+public class RelEngPluginEarlyStartup implements IStartup {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IStartup#earlyStartup()
+ */
+ public void earlyStartup() {
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/messages.properties b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/messages.properties new file mode 100644 index 00000000..f4c4ba40 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/pomversion/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 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 +############################################################################### + +PomVersionErrorReporter_pom_version_error_marker_message=POM artifact version {0} does not match bundle version {1} +PomVersionMarkerResolution_label=Replace version in pom.xml with {0} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java new file mode 100644 index 00000000..4c73bdc4 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * General functions useful to all widgets that create preference blocks + * + * @since 3.8 + */ +public abstract class ConfigurationBlock { + + private static final int HIGHLIGHT_FOCUS = SWT.COLOR_WIDGET_DARK_SHADOW; + private static final int HIGHLIGHT_MOUSE = SWT.COLOR_WIDGET_NORMAL_SHADOW; + private static final int HIGHLIGHT_NONE = SWT.NONE; + + protected void addHighlight(final Composite parent, final Label labelControl, final Combo comboBox) { + comboBox.addFocusListener(new FocusListener() { + public void focusLost(FocusEvent e) { + highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE); + } + public void focusGained(FocusEvent e) { + highlight(parent, labelControl, comboBox, HIGHLIGHT_FOCUS); + } + }); + + MouseTrackAdapter labelComboListener= new MouseTrackAdapter() { + public void mouseEnter(MouseEvent e) { + highlight(parent, labelControl, comboBox, comboBox.isFocusControl() ? HIGHLIGHT_FOCUS : HIGHLIGHT_MOUSE); + } + public void mouseExit(MouseEvent e) { + if (! comboBox.isFocusControl()) + highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE); + } + }; + comboBox.addMouseTrackListener(labelComboListener); + labelControl.addMouseTrackListener(labelComboListener); + + class MouseMoveTrackListener extends MouseTrackAdapter implements MouseMoveListener, MouseListener { + public void mouseExit(MouseEvent e) { + if (! comboBox.isFocusControl()) + highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE); + } + public void mouseMove(MouseEvent e) { + int color= comboBox.isFocusControl() ? HIGHLIGHT_FOCUS : isAroundLabel(e) ? HIGHLIGHT_MOUSE : HIGHLIGHT_NONE; + highlight(parent, labelControl, comboBox, color); + } + public void mouseDown(MouseEvent e) { + if (isAroundLabel(e)) + comboBox.setFocus(); + } + public void mouseDoubleClick(MouseEvent e) { + // not used + } + public void mouseUp(MouseEvent e) { + // not used + } + private boolean isAroundLabel(MouseEvent e) { + int lx= labelControl.getLocation().x; + Rectangle c= comboBox.getBounds(); + int x= e.x; + int y= e.y; + boolean isAroundLabel= lx - 5 < x && x < c.x && c.y - 2 < y && y < c.y + c.height + 2; + return isAroundLabel; + } + } + MouseMoveTrackListener parentListener= new MouseMoveTrackListener(); + parent.addMouseMoveListener(parentListener); + parent.addMouseTrackListener(parentListener); + parent.addMouseListener(parentListener); + + MouseAdapter labelClickListener= new MouseAdapter() { + public void mouseDown(MouseEvent e) { + comboBox.setFocus(); + } + }; + labelControl.addMouseListener(labelClickListener); + } + + protected void highlight(final Composite parent, final Label labelControl, final Combo comboBox, final int color) { + + class HighlightPainter implements PaintListener { + + private int fColor= color; + + public void paintControl(PaintEvent e) { + if (((GridData) labelControl.getLayoutData()).exclude) { + parent.removePaintListener(this); + labelControl.setData(null); + return; + } + + int GAP= 7; + int ARROW= 3; + Rectangle l= labelControl.getBounds(); + Point c= comboBox.getLocation(); + + e.gc.setForeground(e.display.getSystemColor(fColor)); + int x2= c.x - GAP; + int y= l.y + l.height / 2 + 1; + + e.gc.drawLine(l.x + l.width + GAP, y, x2, y); + e.gc.drawLine(x2 - ARROW, y - ARROW, x2, y); + e.gc.drawLine(x2 - ARROW, y + ARROW, x2, y); + } + } + + Object data= labelControl.getData(); + if (data == null) { + if (color != HIGHLIGHT_NONE) { + PaintListener painter= new HighlightPainter(); + parent.addPaintListener(painter); + labelControl.setData(painter); + } else { + return; + } + } else { + if (color == HIGHLIGHT_NONE) { + parent.removePaintListener((PaintListener) data); + labelControl.setData(null); + } else if (color != ((HighlightPainter) data).fColor){ + ((HighlightPainter) data).fColor= color; + } else { + return; + } + } + + parent.redraw(); + parent.update(); + } + +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java new file mode 100644 index 00000000..6fdabdca --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.preferences; + +import org.eclipse.osgi.util.NLS; + + +final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.releng.tools.preferences.messages"; //$NON-NLS-1$ + + public static String PomErrorLevelBlock_mismatched_pom_versions_pref; + public static String PomVersionPreferencePage_pom_pref_message; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + // Do not instantiate + } +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java new file mode 100644 index 00000000..3059194f --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java @@ -0,0 +1,407 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.preferences; + +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.releng.tools.RelEngPlugin; +import org.eclipse.releng.tools.pomversion.IPomVersionConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; +import org.eclipse.ui.preferences.IWorkingCopyManager; +import org.eclipse.ui.preferences.WorkingCopyManager; +import org.osgi.service.prefs.BackingStoreException; + +/** + * This block is used to add error/warning combos to the {@link PomVersionPreferencePage} + * + */ +public class PomErrorLevelBlock extends ConfigurationBlock { + /** + * Provides data information for created controls + */ + protected static class ControlData { + Key key; + private String[] values; + + /** + * Constructor + * @param key + * @param values + */ + public ControlData(Key key, String[] values) { + this.key = key; + this.values = values; + } + + public Key getKey() { + return key; + } + + public String getValue(boolean selection) { + int index= selection ? 0 : 1; + return values[index]; + } + + public String getValue(int index) { + return values[index]; + } + + public int getSelection(String value) { + if (value != null) { + for (int i= 0; i < values.length; i++) { + if (value.equals(values[i])) { + return i; + } + } + } + return values.length -1; // assume the last option is the least severe + } + } + + /** + * Provides management for changed/stored values for a given preference key + */ + protected static class Key { + + private String qualifier; + private String key; + + /** + * Constructor + * @param qualifier + * @param key + */ + public Key(String qualifier, String key) { + this.qualifier= qualifier; + this.key= key; + } + + /** + * Returns the {@link IEclipsePreferences} node for the given context and {@link IWorkingCopyManager} + * @param context + * @param manager + * @return the {@link IEclipsePreferences} node or <code>null</code> + */ + private IEclipsePreferences getNode(IScopeContext context, IWorkingCopyManager manager) { + IEclipsePreferences node = context.getNode(qualifier); + if (manager != null) { + return manager.getWorkingCopy(node); + } + return node; + } + + /** + * Returns the value stored in the {@link IEclipsePreferences} node from the given context and working copy manager + * @param context + * @param manager + * @return the value from the {@link IEclipsePreferences} node or <code>null</code> + */ + public String getStoredValue(IScopeContext context, IWorkingCopyManager manager) { + IEclipsePreferences node = getNode(context, manager); + if(node != null) { + return node.get(key, null); + } + return null; + } + + /** + * Returns the stored value of this {@link IEclipsePreferences} node using a given lookup order, and allowing the + * top scope to be ignored + * @param lookupOrder + * @param ignoreTopScope + * @param manager + * @return the value from the {@link IEclipsePreferences} node or <code>null</code> + */ + public String getStoredValue(IScopeContext[] lookupOrder, boolean ignoreTopScope, IWorkingCopyManager manager) { + for (int i = ignoreTopScope ? 1 : 0; i < lookupOrder.length; i++) { + String value = getStoredValue(lookupOrder[i], manager); + if (value != null) { + return value; + } + } + return null; + } + + /** + * Sets the value of this key + * @param context + * @param value + * @param manager + */ + public void setStoredValue(IScopeContext context, String value, IWorkingCopyManager manager) { + IEclipsePreferences node = getNode(context, manager); + if (value != null) { + node.put(key, value); + } else { + node.remove(key); + } + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return qualifier + '/' + key; + } + } + + private static final Key KEY_POM_VERSION_ERROR_LEVEL = new Key(RelEngPlugin.ID, IPomVersionConstants.POM_VERSION_ERROR_LEVEL); + + /** + * An array of all of the keys for the page + */ + private static Key[] fgAllKeys = { + KEY_POM_VERSION_ERROR_LEVEL + }; + + /** + * Constant representing the severity values presented in the combo boxes for each option + */ + private static final String[] SEVERITIES_LABELS = { + "Error", //$NON-NLS-1$ + "Warning", //$NON-NLS-1$ + "Ignore" //$NON-NLS-1$ + }; + + /** + * Constant representing the severity values presented in the combo boxes for each option + */ + private static final String[] SEVERITIES = { + IPomVersionConstants.VALUE_ERROR, + IPomVersionConstants.VALUE_WARNING, + IPomVersionConstants.VALUE_IGNORE, + }; + + /** + * Default selection listener for controls on the page + */ + private SelectionListener selectionlistener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if(e.widget instanceof Combo) { + Combo combo = (Combo) e.widget; + ControlData data = (ControlData) combo.getData(); + data.key.setStoredValue(fLookupOrder[0], combo.getText(), fManager); + fDirty = true; + } + } + }; + + /** + * Listing of all of the {@link Combo}s added to the block + */ + private Combo fCombo = null; + + /** + * The context of settings locations to search for values in + */ + IScopeContext[] fLookupOrder = null; + + /** + * the working copy manager to work with settings + */ + IWorkingCopyManager fManager = null; + + /** + * The main composite for the configuration block, used for enabling/disabling the block + */ + private Composite fMainComp = null; + + + /** + * Stored old fProject specific settings. + */ + private IdentityHashMap fOldProjectSettings = null; + + /** + * Flag used to know if the page needs saving or not + */ + boolean fDirty = false; + + /** + * Constructor + * @param project + */ + public PomErrorLevelBlock(IWorkbenchPreferenceContainer container) { + fLookupOrder = new IScopeContext[] { + InstanceScope.INSTANCE, + DefaultScope.INSTANCE + }; + if(container == null) { + fManager = new WorkingCopyManager(); + } + else { + fManager = container.getWorkingCopyManager(); + } + fOldProjectSettings = null; + } + + /** + * Creates the control in the parent control + * + * @param parent the parent control + */ + public Control createControl(Composite parent) { + fMainComp = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + fMainComp.setLayout(gl); + fMainComp.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + fMainComp.setFont(parent.getFont()); + this.fCombo = createComboControl(fMainComp, Messages.PomErrorLevelBlock_mismatched_pom_versions_pref, KEY_POM_VERSION_ERROR_LEVEL); + Dialog.applyDialogFont(fMainComp); + return fMainComp; + } + + /** + * Saves all of the changes on the page + */ + public void performOK() { + save(); + } + + /** + * Directly applies all of the changes on the page + */ + public void performApply() { + save(); + } + + /** + * Performs the save operation on the working copy manager + */ + private void save() { + if(fDirty) { + try { + ArrayList changes = new ArrayList(); + collectChanges(fLookupOrder[0], changes); + if(changes.size() > 0) { + fManager.applyChanges(); + } + fDirty = false; + } + catch(BackingStoreException bse) { + RelEngPlugin.log(new Status(IStatus.ERROR, RelEngPlugin.ID, bse.getMessage(), bse)); + } + } + } + + /** + * Cancels all of the changes on the page + */ + public void performCancel() {} + + /** + * Reverts all of the settings back to their defaults + */ + public void performDefaults() { + String defval = null; + for(int i = 0; i < fgAllKeys.length; i++) { + defval = fgAllKeys[i].getStoredValue(fLookupOrder, true, fManager); + fgAllKeys[i].setStoredValue(fLookupOrder[0], defval, fManager); + } + updateCombos(); + fDirty = true; + } + + /** + * Updates all of the registered {@link Combo}s on the page. + * Registration implies that the {@link Combo} control was added to the listing + * of fCombos + */ + private void updateCombos() { + if (this.fCombo != null) { + ControlData data = (ControlData) fCombo.getData(); + this.fCombo.select(data.getSelection(data.getKey().getStoredValue(fLookupOrder, false, fManager))); + } + } + + /** + * Disposes the controls from this page + */ + public void dispose() { + fMainComp.getParent().dispose(); + } + + /** + * Creates a {@link Label} | {@link Combo} control. The combo is initialised from the given {@link Key} + * @param parent + * @param label + * @param key + */ + protected Combo createComboControl(Composite parent, String label, Key key) { + Label lbl = new Label(parent, SWT.NONE); + GridData gd = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + lbl.setLayoutData(gd); + lbl.setText(label); + Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); + gd = new GridData(GridData.END, GridData.CENTER, false, false); + combo.setLayoutData(gd); + ControlData data = new ControlData(key, SEVERITIES); + combo.setData(data); + combo.setItems(SEVERITIES_LABELS); + combo.addSelectionListener(selectionlistener); + combo.select(data.getSelection(key.getStoredValue(fLookupOrder, false, fManager))); + addHighlight(parent, lbl, combo); + return combo; + } + + /** + * Collects the keys that have changed on the page into the specified list + * @param changes the {@link List} to collect changed keys into + */ + private void collectChanges(IScopeContext context, List changes) { + Key key = null; + String origval = null, + newval = null; + boolean complete = fOldProjectSettings == null; + for(int i = 0; i < fgAllKeys.length; i++) { + key = fgAllKeys[i]; + origval = key.getStoredValue(context, null); + newval = key.getStoredValue(context, fManager); + if(newval == null) { + if(origval != null) { + changes.add(key); + } + else if(complete) { + key.setStoredValue(context, key.getStoredValue(fLookupOrder, true, fManager), fManager); + changes.add(key); + } + } + else if(!newval.equals(origval)) { + changes.add(key); + } + } + } + + public static Key[] getAllKeys() { + return fgAllKeys; + } +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java new file mode 100644 index 00000000..7231d8ed --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + *******************************************************************************/ +package org.eclipse.releng.tools.preferences; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.releng.tools.RelEngPlugin; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; + +/** + * This preference page allows the error level of the POM version tool to be set + */ +public class PomVersionPreferencePage extends PreferencePage implements + IWorkbenchPreferencePage { + + public static final String ID = RelEngPlugin.ID + "PomVersionPreferencePage"; //$NON-NLS-1$ + + /** + * The main configuration block for the page + */ + private PomErrorLevelBlock block = null; + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + comp.setLayout(gl); + comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Label label = new Label(comp, SWT.WRAP); + GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false); + gd.widthHint = 400; + label.setLayoutData(gd); + label.setText(Messages.PomVersionPreferencePage_pom_pref_message); + label.setFont(comp.getFont()); + + block = new PomErrorLevelBlock((IWorkbenchPreferenceContainer)getContainer()); + block.createControl(comp); + Dialog.applyDialogFont(comp); + return comp; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performCancel() + */ + public boolean performCancel() { + if (this.block != null) { + this.block.performCancel(); + } + return super.performCancel(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performOk() + */ + public boolean performOk() { + this.block.performOK(); + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performApply() + */ + protected void performApply() { + this.block.performApply(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + protected void performDefaults() { + this.block.performDefaults(); + } +} diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java index efaf42c3..4339ddf2 100644 --- a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2013 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 @@ -14,6 +14,7 @@ import java.util.Calendar; import org.eclipse.releng.tools.Messages; import org.eclipse.releng.tools.RelEngPlugin; +import org.eclipse.releng.tools.pomversion.IPomVersionConstants; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; @@ -40,6 +41,8 @@ public class RelEngPreferenceInitializer extends AbstractPreferenceInitializer { store.setDefault(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY, false); store.setDefault(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY, false); store.setDefault(RelEngCopyrightConstants.IGNORE_XML_KEY, false); + + store.setDefault(IPomVersionConstants.POM_VERSION_ERROR_LEVEL, IPomVersionConstants.VALUE_IGNORE); } } diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties new file mode 100644 index 00000000..0a6b76d4 --- /dev/null +++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2013 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 +############################################################################### + +PomErrorLevelBlock_mismatched_pom_versions_pref=&Mismatched plug-in and pom.xml version numbers +PomVersionPreferencePage_pom_pref_message=The POM Version tool will compare the artifact version in a pom.xml file at the root of the project to the plug-in version in the manifest. If the two versions do not match a problem marker will be created. The severity of this problem can be configured on this page. |