aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaloyan Raev2013-12-09 08:16:46 (EST)
committerGerrit Code Review @ Eclipse.org2014-01-23 11:43:29 (EST)
commit79b136f83abefea996cd69b204b4acede63ca543 (patch)
treef2cc1adb7b77fab6c7d32b546788ecc347555948
parent655492cc23bade8a400c2416b3dead73f6edaf13 (diff)
downloadorg.eclipse.pdt-79b136f83abefea996cd69b204b4acede63ca543.zip
org.eclipse.pdt-79b136f83abefea996cd69b204b4acede63ca543.tar.gz
org.eclipse.pdt-79b136f83abefea996cd69b204b4acede63ca543.tar.bz2
Bug 424340 - Library Foldersrefs/changes/80/19980/11
Details available in the document attached to the bug. Bug: 424340 Change-Id: Ic5ad8452a2908e8f577cdac11601f515cdadc3b1 Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>
-rw-r--r--plugins/org.eclipse.php.core/META-INF/MANIFEST.MF39
-rw-r--r--plugins/org.eclipse.php.core/plugin.properties1
-rw-r--r--plugins/org.eclipse.php.core/plugin.xml24
-rw-r--r--plugins/org.eclipse.php.core/schema/libraryFolderNameProviders.exsd119
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderChangeListener.java53
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderNameProvider.java64
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/LibraryFolderManager.java708
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/Messages.java28
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/RenameLibraryFolderChange.java77
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/messages.properties1
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/PHPCorePlugin.java4
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/builder/ParserBuildParticipantFactory.java14
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderJob.java167
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderListener.java41
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/LibraryFolderRenameParticipant.java75
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/Messages.java28
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/OpenedAndChangedProjectsFinder.java120
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/messages.properties1
-rw-r--r--plugins/org.eclipse.php.ui/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.php.ui/icons/full/obj16/libfolder_obj.gifbin0 -> 339 bytes
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java16
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/LibraryFolderActionGroup.java151
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/Messages.java4
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/PHPExplorerActionGroup.java3
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsLibraryFolderAction.java82
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsSourceFolderAction.java153
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/messages.properties4
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/LibraryFolderChangeListener.java98
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/PHPExplorerLabelProvider.java20
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/preferences/includepath/PHPIPListLabelProvider.java12
-rw-r--r--plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/util/PHPPluginImages.java18
31 files changed, 2070 insertions, 58 deletions
diff --git a/plugins/org.eclipse.php.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.php.core/META-INF/MANIFEST.MF
index 27a86ab..6d680fc 100644
--- a/plugins/org.eclipse.php.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.php.core/META-INF/MANIFEST.MF
@@ -17,13 +17,15 @@ Require-Bundle: org.eclipse.core.runtime,
com.ibm.icu;bundle-version="4.0.1",
org.eclipse.php.core.parser,
org.eclipse.dltk.core.index.sql,
- org.eclipse.wst.common.project.facet.core
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.ltk.core.refactoring
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.php.core.codeassist,
org.eclipse.php.core.compiler,
org.eclipse.php.core.format,
org.eclipse.php.core.index,
org.eclipse.php.core.language,
+ org.eclipse.php.core.libfolders,
org.eclipse.php.internal.core;
x-friends:="org.eclipse.php.core.performance.tests,
org.eclipse.php.core.tests,
@@ -135,17 +137,6 @@ Export-Package: org.eclipse.php.core.codeassist,
org.eclipse.php.ui.performance.tests,
org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.ast.scanner.php54,
- org.eclipse.php.internal.core.ast.util;
- x-friends:="org.eclipse.php.core.performance.tests,
- org.eclipse.php.core.tests,
- org.eclipse.php.debug.core,
- org.eclipse.php.debug.daemon,
- org.eclipse.php.debug.ui,
- org.eclipse.php.server.core,
- org.eclipse.php.server.ui,
- org.eclipse.php.ui,
- org.eclipse.php.ui.performance.tests,
- org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.ast.scanner.php55,
org.eclipse.php.internal.core.ast.util;
x-friends:="org.eclipse.php.core.performance.tests,
@@ -302,17 +293,6 @@ Export-Package: org.eclipse.php.core.codeassist,
org.eclipse.php.ui.performance.tests,
org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.compiler.ast.parser.php54,
- org.eclipse.php.internal.core.compiler.ast.visitor;
- x-friends:="org.eclipse.php.core.performance.tests,
- org.eclipse.php.core.tests,
- org.eclipse.php.debug.core,
- org.eclipse.php.debug.daemon,
- org.eclipse.php.debug.ui,
- org.eclipse.php.server.core,
- org.eclipse.php.server.ui,
- org.eclipse.php.ui,
- org.eclipse.php.ui.performance.tests,
- org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.compiler.ast.parser.php55,
org.eclipse.php.internal.core.compiler.ast.visitor;
x-friends:="org.eclipse.php.core.performance.tests,
@@ -324,7 +304,7 @@ Export-Package: org.eclipse.php.core.codeassist,
org.eclipse.php.server.ui,
org.eclipse.php.ui,
org.eclipse.php.ui.performance.tests,
- org.eclipse.php.ui.tests",
+ org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.corext;
x-friends:="org.eclipse.php.core.performance.tests,
org.eclipse.php.core.tests,
@@ -447,17 +427,6 @@ Export-Package: org.eclipse.php.core.codeassist,
org.eclipse.php.ui.performance.tests,
org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.documentModel.parser.php54,
- org.eclipse.php.internal.core.documentModel.parser.regions;
- x-friends:="org.eclipse.php.core.performance.tests,
- org.eclipse.php.core.tests,
- org.eclipse.php.debug.core,
- org.eclipse.php.debug.daemon,
- org.eclipse.php.debug.ui,
- org.eclipse.php.server.core,
- org.eclipse.php.server.ui,
- org.eclipse.php.ui,
- org.eclipse.php.ui.performance.tests,
- org.eclipse.php.ui.tests",
org.eclipse.php.internal.core.documentModel.parser.php55,
org.eclipse.php.internal.core.documentModel.parser.regions;
x-friends:="org.eclipse.php.core.performance.tests,
diff --git a/plugins/org.eclipse.php.core/plugin.properties b/plugins/org.eclipse.php.core/plugin.properties
index 1d893e8..9869907 100644
--- a/plugins/org.eclipse.php.core/plugin.properties
+++ b/plugins/org.eclipse.php.core/plugin.properties
@@ -16,6 +16,7 @@ content-type.name.0=PHP Content Type
PHPTaskMarker.label=PHP Task
parserBuildParticipant.name=PHP Parser
+libraryFolderRenameParticipant.name = Library Folder Rename
content-type.name = Configuration Files \ No newline at end of file
diff --git a/plugins/org.eclipse.php.core/plugin.xml b/plugins/org.eclipse.php.core/plugin.xml
index 86f64c9..f01e17d 100644
--- a/plugins/org.eclipse.php.core/plugin.xml
+++ b/plugins/org.eclipse.php.core/plugin.xml
@@ -19,7 +19,8 @@
<extension-point id="completionContextResolvers" name="PHP Completion Context Resolver" schema="schema/completionContextResolvers.exsd" />
<extension-point id="languageModelProviders" name="PHP Language Model Provider" schema="schema/languageModelProviders.exsd"/>
<extension-point id="phpFormatterCommonPreferences" name="PHP Code Formatter Common Preferences" schema="schema/phpFormatterCommonPreferences.exsd"/>
- <extension-point id="indentationStrategy" name="Indentation Strategy Extension" schema="schema/indentationStrategy.exsd"/>
+ <extension-point id="indentationStrategy" name="Indentation Strategy Extension" schema="schema/libraryFolderNameProviders.exsd"/>
+ <extension-point id="libraryFolderNameProviders" name="Library Folder Name Providers" schema="schema/libraryFolderNameProviders.exsd"/>
<!-- PHP Model Handler -->
<extension
@@ -396,4 +397,25 @@
<delegate class="org.eclipse.php.internal.core.facet.VersionChangeActionDelegate" />
</action>
</extension>
+ <extension
+ point="org.eclipse.ltk.core.refactoring.renameParticipants">
+ <renameParticipant
+ class="org.eclipse.php.internal.core.libfolders.LibraryFolderRenameParticipant"
+ name="%libraryFolderRenameParticipant.name"
+ id="org.eclipse.php.core.refactoring.libraryFolderRename">
+ <enablement>
+ <with variable="affectedNatures">
+ <iterate operator="or">
+ <equals value="org.eclipse.php.core.PHPNature"/>
+ </iterate>
+ </with>
+ <with variable="element">
+ <or>
+ <instanceof value="org.eclipse.dltk.core.IProjectFragment"/>
+ <instanceof value="org.eclipse.dltk.core.IScriptFolder"/>
+ </or>
+ </with>
+ </enablement>
+ </renameParticipant>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.php.core/schema/libraryFolderNameProviders.exsd b/plugins/org.eclipse.php.core/schema/libraryFolderNameProviders.exsd
new file mode 100644
index 0000000..add4985
--- /dev/null
+++ b/plugins/org.eclipse.php.core/schema/libraryFolderNameProviders.exsd
@@ -0,0 +1,119 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.php.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.php.core" id="libraryFolderNameProviders" name="Library Folder Name Providers"/>
+ </appInfo>
+ <documentation>
+ This extension point allows contributors to provide the library folder manager with common names for library folders according to some convention of a framework or a tool, e.g. &quot;vendor&quot; is a common name for a library folder when using Composer. These names are used when automatically detecting library folders for PHP projects.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="provider"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="provider">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ fully qualified name of a Java class that implements &lt;code&gt;ILibraryFolderNameProvider&lt;/code&gt;.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.php.core.libfolders.ILibraryFolderNameProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.3
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ The following is an example of a library folder name provider extension:
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.php.core.libraryFolderNameProviders&quot;&gt;
+ &lt;provider
+ class=&quot;com.example.ExampleLibraryFolderNameProvider&quot;&gt;
+ &lt;/provider&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+In the example above, the specified library folder name provider will be consulted for common names for library folders.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ Value of the attribute class must be a fully qualified name of a Java class that implements the interface &lt;b&gt;org.eclipse.php.core.libfolders.ILibraryFolderNameProvider&lt;/b&gt;.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ The library folder manager consults this extension point when automatically detecting library folders for a given project. The default implementation of the library folder manager does not assume any common name for library folders and relies only on those contributed to this extension point.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2014 Zend Technologies and others.&lt;br&gt;
+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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderChangeListener.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderChangeListener.java
new file mode 100644
index 0000000..24459f5
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderChangeListener.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.core.libfolders;
+
+import org.eclipse.dltk.core.IModelElement;
+
+/**
+ * A library folder change listeners whenever a source folder is turned to
+ * library folder and vice versa.
+ *
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ * @since 3.3
+ */
+public interface ILibraryFolderChangeListener {
+
+ /**
+ * Notifies this listener that some folders have changed from source folders
+ * to library folders or vice versa.
+ *
+ * <p>
+ * This method is called by the {@link LibraryFolderManager}. It is not
+ * intended to be called directly by clients.
+ * </p>
+ *
+ * <p>
+ * This method is called after the WTP Validation Framework is updated with
+ * the changed folder, but before the re-validation has been started.
+ * </p>
+ *
+ * <p>
+ * Clients must provide a fast and non-blocking implementation of this
+ * method. If a long-running operation is required, it must be executed in a
+ * job.
+ * </p>
+ *
+ * @param elements
+ * the model elements representing the changed folders
+ */
+ public void folderChanged(IModelElement[] elements);
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderNameProvider.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderNameProvider.java
new file mode 100644
index 0000000..708319d
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/ILibraryFolderNameProvider.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.core.libfolders;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * Provides common names for library folders according to some convention of a
+ * framework or a tool, e.g. "vendor" is a common name for a library folder when
+ * using Composer. These names are used when automatically detecting library
+ * folders for PHP projects.
+ *
+ * <p>
+ * This interface is associated with a library folder name provider extension.
+ * </p>
+ *
+ * <p>
+ * The following is an example of a library folder name provider extension:
+ *
+ * <pre>
+ * &lt;extension point=&quot;org.eclipse.php.core.libraryFolderNameProviders&quot;&gt;
+ * &lt;provider
+ * class=&quot;com.example.ExampleLibraryFolderNameProvider&quot;&gt;
+ * &lt;/provider&gt;
+ * &lt;/extension&gt;
+ * </pre>
+ *
+ * </p>
+ *
+ * <p>
+ * In the example above, the specified library folder name provider will be
+ * consulted for common names for library folders.
+ * </p>
+ *
+ * <p>
+ * Clients contributing library folder name providers must implement this
+ * interface.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ * @since 3.3
+ */
+public interface ILibraryFolderNameProvider {
+
+ /**
+ * Returns the common names for library folders which applicable for the
+ * given project.
+ *
+ * @param project
+ * a project
+ *
+ * @return an array of folder names
+ */
+ public String[] getLibraryFolderNames(IProject project);
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/LibraryFolderManager.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/LibraryFolderManager.java
new file mode 100644
index 0000000..3873c3b
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/LibraryFolderManager.java
@@ -0,0 +1,708 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.core.libfolders;
+
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dltk.core.*;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.libfolders.AutoDetectLibraryFolderListener;
+import org.eclipse.wst.validation.ValidationFramework;
+import org.eclipse.wst.validation.internal.DisabledResourceManager;
+
+/**
+ * Provides the necessary API for working with library folders.
+ *
+ * <p>
+ * Library folders are source folders containing code, which is not
+ * application-specific. This code is not validated, but is still accessible for
+ * content assist.
+ * </p>
+ *
+ * <p>
+ * This class is a singleton. Use the {@link #getInstance()} to obtain an
+ * instance of the class.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ * @since 3.3
+ */
+public class LibraryFolderManager {
+
+ /**
+ * The singleton's instance
+ */
+ private static LibraryFolderManager instance;
+
+ /**
+ * The collection of registered library folder change listeners.
+ */
+ private Collection<ILibraryFolderChangeListener> listeners;
+
+ /**
+ * Private constructor to initialize the library folder manager.
+ *
+ * <p>
+ * This constructor should not be called by clients. Use the
+ * {@link #getInstance()} to obtain an instance of the class.
+ * </p>
+ *
+ * <p>
+ * This constructor registers the {@link AutoDetectLibraryFolderListener} as
+ * a resource change listener.
+ * </p>
+ */
+ private LibraryFolderManager() {
+ listeners = Collections
+ .synchronizedSet(new HashSet<ILibraryFolderChangeListener>());
+
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ new AutoDetectLibraryFolderListener(),
+ IResourceChangeEvent.POST_CHANGE);
+ }
+
+ /**
+ * Returns the instance of the singleton class.
+ *
+ * @return an instance of <code>LibraryFolderManager</code>.
+ */
+ public static LibraryFolderManager getInstance() {
+ if (instance == null) {
+ instance = new LibraryFolderManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Adds the given listener for library folder change events. Has no effect
+ * if an identical listener is already registered.
+ *
+ * <p>
+ * The listener will be notified whenever a source folder is turned to
+ * library folder and vice versa.
+ * </p>
+ *
+ * @param listener
+ * the listener
+ */
+ public void addListener(ILibraryFolderChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Removes the given library folder change listener from this workspace. Has
+ * no effect if an identical listener is not registered.
+ *
+ * @param listener
+ * the listener
+ */
+ public void removeListener(ILibraryFolderChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Marks the given source folders as library folders.
+ *
+ * <p>
+ * The given array of model elements should contain {@link IScriptFolder} or
+ * {@link IProjectFragment} objects.
+ * </p>
+ *
+ * <p>
+ * This method executes the following steps:
+ * <ol>
+ * <li>Disables the given folders in the WTP Validation Framework.</li>
+ * <li>Notifies the registered library folder change listeners, e.g. for
+ * updating the images of the given folders and all their subfolders in the
+ * PHP Explorer.</li>
+ * <li>Waits for any running validation job to finish.</li>
+ * <li>Deletes all problem and task markers on all the children resources of
+ * the given folders.</li>
+ * </ol>
+ * </p>
+ *
+ * <p>
+ * This method usually executes a significant number of resource
+ * modifications. It is highly recommended that this method is called either
+ * in a {@link WorkspaceModifyOperation} or in a {@link WorkspaceJob} to
+ * batch the resource change notifications and avoid running unnecessary
+ * build jobs.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements that represents the source folders
+ * to be marked as library folders
+ * @param monitor
+ * a progress monitor, or null if progress reporting is not
+ * desired
+ *
+ * @throws OperationCanceledException
+ * if the progress monitor is canceled while waiting
+ * @throws InterruptedException
+ * if this thread is interrupted while waiting
+ * @throws CoreException
+ * if this method fails for some other reason
+ *
+ * @see {@link #useAsSourceFolder(IModelElement[], IProgressMonitor)}
+ */
+ public void useAsLibraryFolder(IModelElement[] elements,
+ IProgressMonitor monitor) throws OperationCanceledException,
+ InterruptedException, CoreException {
+ disableValidation(elements);
+
+ elements = removeNonExisting(elements);
+ if (elements.length > 0) {
+ notifyListeners(elements);
+ waitValidationJobs(monitor);
+ deleteMarkers(elements);
+ }
+ }
+
+ /**
+ * Marks the given library folders as source folders.
+ *
+ * <p>
+ * The given array of model elements should contain {@link IScriptFolder} or
+ * {@link IProjectFragment} objects.
+ * </p>
+ *
+ * <p>
+ * This method executes the following steps:
+ * <ol>
+ * <li>Enables the given folders in the WTP Validation Framework.</li>
+ * <li>Notifies the registered library folder change listeners, e.g. for
+ * updating the images of the given folders and all their subfolders in the
+ * PHP Explorer.</li>
+ * <li>Waits for any running validation job to finish.</li>
+ * <li>Invokes {@link IResource#touch(IProgressMonitor)} on all the children
+ * of the selected folders. This triggers the necessary builders to
+ * re-validate these resources.</li>
+ * </ol>
+ * </p>
+ *
+ * <p>
+ * This method usually executes a significant number of resource
+ * modifications. It is highly recommended that this method is called either
+ * in a {@link WorkspaceModifyOperation} or in a {@link WorkspaceJob} to
+ * batch the resource change notifications and avoid running unnecessary
+ * build jobs.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements that represents the library folders
+ * to be marked as source folders
+ * @param monitor
+ * a progress monitor, or null if progress reporting is not
+ * desired
+ *
+ * @throws OperationCanceledException
+ * if the progress monitor is canceled while waiting
+ * @throws InterruptedException
+ * if this thread is interrupted while waiting
+ * @throws CoreException
+ * if this method fails for some other reason
+ *
+ * @see {@link #useAsLibraryFolder(IModelElement[], IProgressMonitor)}
+ */
+ public void useAsSourceFolder(IModelElement[] elements,
+ IProgressMonitor monitor) throws OperationCanceledException,
+ InterruptedException, CoreException {
+ enableValidation(elements);
+
+ elements = removeNonExisting(elements);
+ if (elements.length > 0) {
+ notifyListeners(elements);
+ waitValidationJobs(monitor);
+ revalidate(elements, monitor);
+ }
+ }
+
+ /**
+ * Enables validation for the given model element in the WTP Validation
+ * Framework.
+ *
+ * @param element
+ * a model elements to enable validation for
+ */
+ public void enableValidation(IModelElement element) {
+ ValidationFramework vf = ValidationFramework.getDefault();
+ vf.enableValidation(element.getResource());
+ }
+
+ /**
+ * Disables validation for the given model element in the WTP Validation
+ * Framework.
+ *
+ * <p>
+ * This method cleans up the disabled state for all subfolders of the given
+ * model element (i.e. source folder). This is necessary to avoid nested
+ * declarations of library folders. Otherwise, if the user marks a library
+ * folder as a source folder and there are nested library folders then there
+ * will be still subfolders which remain library folders.
+ * </p>
+ *
+ * @param elements
+ * a model element to disable validation for
+ *
+ * @throws ModelException
+ * if the given element does not exist or if an exception occurs
+ * while accessing its corresponding resource
+ */
+ public void disableValidation(IModelElement element) throws ModelException {
+ ValidationFramework vf = ValidationFramework.getDefault();
+
+ // clean up the state of all subfolders
+ for (IModelElement subfolder : getAllSubfolders(element)) {
+ vf.enableValidation(subfolder.getResource());
+ }
+
+ if (!isInLibraryFolder(element)) {
+ // disable the given folder only if no parent folder is a library
+ // folder yet
+ vf.disableValidation(element.getResource());
+ }
+ }
+
+ /**
+ * Enables validation for the given model elements in the WTP Validation
+ * Framework.
+ *
+ * <p>
+ * This method invokes {@link #enableValidation(IModelElement)} for each of
+ * the model elements in the given array.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements to enable validation for
+ */
+ public void enableValidation(IModelElement[] elements) {
+ for (IModelElement element : elements) {
+ enableValidation(element);
+ }
+ }
+
+ /**
+ * Disables validation for the given model elements in the WTP Validation
+ * Framework.
+ *
+ * <p>
+ * This method invokes {@link #disableValidation(IModelElement)} for each of
+ * the model elements in the given array.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements to disable validation for
+ *
+ * @throws ModelException
+ * if any of the given element does not exist or if an exception
+ * occurs while accessing its corresponding resource
+ */
+ public void disableValidation(IModelElement[] elements)
+ throws ModelException {
+ for (IModelElement element : elements) {
+ disableValidation(element);
+ }
+ }
+
+ /**
+ * Returns whether the given resource is inside a library folder.
+ *
+ * <p>
+ * A library folder is a source folder that is disabled for validation in
+ * the WTP Validation Framework. So, this method checks if a parent folder
+ * of the given model element is disabled for validation.
+ * </p>
+ *
+ * @param resource
+ * a resource to check if inside a library folder
+ *
+ * @return <code>true</code> if the given model element is inside a library
+ * folder, and <code>false</code> otherwise
+ *
+ * @see ValidationFramework#disableValidation(IResource)
+ */
+ public boolean isInLibraryFolder(IResource resource) {
+ if (resource == null)
+ // the model element has no corresponding resource, so it is not
+ // part of any source file and hence cannot be in a library folder
+ return false;
+
+ if (resource.getType() == IResource.FILE) {
+ // the model element is a source file, so take its parent folder
+ resource = resource.getParent();
+ }
+
+ while (resource.getType() == IResource.FOLDER) {
+ // check if the folder is disabled in the WTP Validation Framework
+ if (isTopmostLibraryFolder(resource)) {
+ return true;
+ }
+ // the folder is not disabled, so check its parent folder
+ resource = resource.getParent();
+ }
+
+ // none of the element's parent folders is disabled in the WTP
+ // Validation Framework, so the element is not inside a library folder
+ return false;
+ }
+
+ /**
+ * Returns whether the given model element is inside a library folder.
+ *
+ * <p>
+ * A library folder is a source folder that is disabled for validation in
+ * the WTP Validation Framework. So, this method checks if a parent folder
+ * of the given model element is disabled for validation.
+ * </p>
+ *
+ * @param element
+ * a model element to check if inside a library folder
+ *
+ * @return <code>true</code> if the given model element is inside a library
+ * folder, and <code>false</code> otherwise
+ *
+ * @see ValidationFramework#disableValidation(IResource)
+ */
+ public boolean isInLibraryFolder(IModelElement element) {
+ if (element == null)
+ return false;
+
+ IResource resource = element.getResource();
+
+ return isInLibraryFolder(resource);
+ }
+
+ /**
+ * Returns whether the the given resource is a topmost library folder.
+ *
+ * <p>
+ * A topmost library folder is such folder that is explicitly disable in the
+ * WTP Validation Framework. The subfolders of a topmost library folder are
+ * library folders, but the parent of the topmost library folder is not a
+ * library folder.
+ * </p>
+ *
+ * @param resource
+ * a resource
+ *
+ * @return <code>true</code> if the resource is a topmost library folder,
+ * and <code>false</code> otherwise
+ */
+ @SuppressWarnings("restriction")
+ public boolean isTopmostLibraryFolder(IResource resource) {
+ return DisabledResourceManager.getDefault().isDisabled(resource);
+ }
+
+ /**
+ * Returns whether the the given model element is a topmost library folder.
+ *
+ * <p>
+ * A topmost library folder is such folder that is explicitly disable in the
+ * WTP Validation Framework. The subfolders of a topmost library folder are
+ * library folders, but the parent of the topmost library folder is not a
+ * library folder.
+ * </p>
+ *
+ * @param element
+ * a model element
+ *
+ * @return <code>true</code> if the model element is a topmost library
+ * folder, and <code>false</code> otherwise
+ */
+ public boolean isTopmostLibraryFolder(IModelElement element) {
+ return isTopmostLibraryFolder(element.getResource());
+ }
+
+ /**
+ * Returns the topmost library folder of the given model element.
+ *
+ * <p>
+ * A topmost library folder is such folder that is explicitly disable in the
+ * WTP Validation Framework. The subfolders of a topmost library folder are
+ * library folders, but the parent of the topmost library folder is not a
+ * library folder.
+ * </p>
+ *
+ * @param element
+ * a model element
+ *
+ * @return the topmost library folder of the given model element
+ */
+ public IModelElement getTopmostLibraryFolder(IModelElement element) {
+ IResource resource = element.getResource();
+ if (resource == null)
+ // the model element has no corresponding resource, so it is not
+ // part of any source file and hence cannot be in a library folder
+ return null;
+
+ if (resource.getType() == IResource.FILE) {
+ // the model element is a source file, so take its parent folder
+ resource = resource.getParent();
+ }
+
+ while (resource.getType() == IResource.FOLDER) {
+ // check if the folder is disabled in the WTP Validation Framework
+ if (isTopmostLibraryFolder(resource)) {
+ // the folder is disabled, so it is the topmost library folder
+ return DLTKCore.create(resource);
+ }
+ // the folder is not disabled, so check its parent folder
+ resource = resource.getParent();
+ }
+
+ // none of the element's parent folders is disabled in the WTP
+ // Validation Framework, so the element is not inside a library folder
+ // and therefore has no topmost library folder
+ return null;
+ }
+
+ /**
+ * Returns all subfolders of the given model elements.
+ *
+ * <p>
+ * This method invokes {@link #getAllSubfolders(IModelElement)} for each of
+ * the model elements in the given array and merges the result.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements
+ *
+ * @return an array of model elements containing the elements of the given
+ * array and all their children
+ *
+ * @throws ModelException
+ * if any of the given element does not exist or if an exception
+ * occurs while accessing its corresponding resource
+ */
+ public IModelElement[] getAllSubfolders(IModelElement[] elements)
+ throws ModelException {
+ Collection<IModelElement> allSubfolders = new HashSet<IModelElement>();
+
+ for (IModelElement element : elements) {
+ allSubfolders.addAll(Arrays.asList(getAllSubfolders(element)));
+ }
+
+ return allSubfolders.toArray(new IModelElement[allSubfolders.size()]);
+ }
+
+ /**
+ * Returns all subfolders of the given model element.
+ *
+ * <p>
+ * This method traverses the complete element's subtree to find the
+ * subfolders on all levels.
+ * </p>
+ *
+ * @param element
+ * a model element
+ *
+ * @return an array of model elements containing the given element and all
+ * its children
+ *
+ * @throws ModelException
+ * if any of the given element does not exist or if an exception
+ * occurs while accessing its corresponding resource
+ */
+ public IModelElement[] getAllSubfolders(IModelElement element)
+ throws ModelException {
+ List<IModelElement> children = new ArrayList<IModelElement>();
+
+ IPath path = element.getPath();
+
+ // check all project fragments in the project
+ IProjectFragment[] fragments = element.getScriptProject()
+ .getProjectFragments();
+
+ for (IProjectFragment fragment : fragments) {
+ if (pathContainsModelElement(path, fragment)) {
+ // the project fragment is in the path
+ children.add(fragment);
+ }
+
+ // check all script folders in the project fragment
+ for (IModelElement child : fragment.getChildren()) {
+ if (child.getElementType() == IModelElement.SCRIPT_FOLDER
+ && pathContainsModelElement(path, child)) {
+ // the script folder is in the path
+ children.add(child);
+ }
+ }
+ }
+
+ return children.toArray(new IModelElement[children.size()]);
+ }
+
+ /**
+ * Notifies the registered library folder change listeners that the given
+ * folders have changed from source folders to library folders or vice
+ * versa.
+ *
+ * @param elements
+ * the model elements representing the changed folders
+ */
+ private void notifyListeners(IModelElement[] elements) {
+ synchronized (listeners) {
+ for (ILibraryFolderChangeListener listener : listeners) {
+ try {
+ listener.folderChanged(elements);
+ } catch (Exception e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the non-existing model elements from the given array.
+ *
+ * <p>
+ * The result is returned as new array. The given array remains untouched.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements
+ *
+ * @return a new array that contains only the existing elements of the given
+ * array
+ */
+ private IModelElement[] removeNonExisting(IModelElement[] elements) {
+ Collection<IModelElement> existing = new HashSet<IModelElement>();
+
+ for (IModelElement element : elements) {
+ if (element.exists()) {
+ existing.add(element);
+ }
+ }
+
+ return existing.toArray(new IModelElement[existing.size()]);
+ }
+
+ /**
+ * Returns whether the given path contains the given model element.
+ *
+ * <p>
+ * This method compares if the path of the given model element is a subpath
+ * of the given path.
+ * </p>
+ *
+ * @param path
+ * a path
+ * @param element
+ * a model element
+ *
+ * @return <code>true</code> if the given model element is in the given
+ * path, and <code>false</code> otherwise
+ */
+ private boolean pathContainsModelElement(IPath path, IModelElement element) {
+ // get the first segments from the elements path
+ IPath elementPathPrefix = element.getPath().uptoSegment(
+ path.segmentCount());
+
+ // compare the prefix with the given path
+ return path.equals(elementPathPrefix);
+ }
+
+ /**
+ * Delete all problem and tasks markers on all the given model elements and
+ * all their children.
+ *
+ * <p>
+ * Only markers of types {@link IMarker#PROBLEM} and {@link IMarker#TASK}
+ * and their subtypes are deleted. Markers of other types (bookmarks,
+ * breakpoints, etc.) are not affected.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements
+ *
+ * @throws CoreException
+ * if deleting the markers on any resource fails
+ */
+ private void deleteMarkers(IModelElement[] elements) throws CoreException {
+
+ for (IModelElement element : elements) {
+ element.getResource().deleteMarkers(IMarker.PROBLEM, true,
+ IResource.DEPTH_INFINITE);
+ element.getResource().deleteMarkers(IMarker.TASK, true,
+ IResource.DEPTH_INFINITE);
+ }
+ }
+
+ /**
+ * Triggers validation jobs for the given model elements and all their
+ * children.
+ *
+ * @param elements
+ * an array of model elements
+ * @param monitor
+ * a progress monitor, or null if progress reporting is not
+ * desired
+ *
+ * @throws CoreException
+ * if touching of any of the resources fails
+ */
+ private void revalidate(IModelElement[] elements, IProgressMonitor monitor)
+ throws CoreException {
+ for (IModelElement element : elements) {
+ deepTouch(element.getResource(), monitor);
+ }
+ }
+
+ /**
+ * Invokes {@link IResource#touch(IProgressMonitor)} on the given resource
+ * and all its children.
+ *
+ * @param resource
+ * a resource to touch
+ * @param monitor
+ * a progress monitor, or null if progress reporting is not
+ * desired
+ *
+ * @throws CoreException
+ * if touching of any of the resources fails
+ */
+ private void deepTouch(IResource resource, IProgressMonitor monitor)
+ throws CoreException {
+ resource.touch(monitor);
+
+ // touch recursively resources inside folders and projects
+ if (resource instanceof IContainer) {
+ IContainer container = (IContainer) resource;
+ for (IResource member : container.members()) {
+ deepTouch(member, monitor);
+ }
+ }
+ }
+
+ /**
+ * Waits for any running jobs of the WTP Validation Framework to finish.
+ *
+ * @param monitor
+ * a progress monitor, or null if progress reporting is not
+ * desired
+ *
+ * @throws OperationCanceledException
+ * if the progress monitor is canceled while waiting
+ * @throws InterruptedException
+ * if this thread is interrupted while waiting
+ */
+ private void waitValidationJobs(IProgressMonitor monitor)
+ throws OperationCanceledException, InterruptedException {
+ Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, monitor);
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/Messages.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/Messages.java
new file mode 100644
index 0000000..61713a6
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/Messages.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.core.libfolders;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Kaloyan Raev
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.php.core.libfolders.messages"; //$NON-NLS-1$
+ public static String RenameLibraryFolderChange_name;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/RenameLibraryFolderChange.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/RenameLibraryFolderChange.java
new file mode 100644
index 0000000..59e9d9c
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/RenameLibraryFolderChange.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.core.libfolders;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A refactoring change that updates the WTP Validation Framework when a library
+ * folder is renamed or moved.
+ *
+ * @author Kaloyan Raev
+ */
+public class RenameLibraryFolderChange extends Change {
+
+ private IModelElement fElement;
+ private IModelElement fNewElement;
+
+ /**
+ * Creates the change.
+ *
+ * @param element
+ * the model element of the library folder to be renamed or moved
+ * @param newElement
+ * the model element of the renamed/moved library folder
+ */
+ public RenameLibraryFolderChange(IModelElement element,
+ IModelElement newElement) {
+ fElement = element;
+ fNewElement = newElement;
+ }
+
+ @Override
+ public Object getModifiedElement() {
+ return fElement;
+ }
+
+ @Override
+ public String getName() {
+ return NLS.bind(Messages.RenameLibraryFolderChange_name,
+ fNewElement.getElementName());
+ }
+
+ @Override
+ public void initializeValidationData(IProgressMonitor monitor) {
+ }
+
+ @Override
+ public RefactoringStatus isValid(IProgressMonitor monitor)
+ throws CoreException, OperationCanceledException {
+ return new RefactoringStatus();
+ }
+
+ @Override
+ public Change perform(IProgressMonitor monitor) throws CoreException {
+ // update the WTP Validation Framework for the renamed folder
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+ lfm.enableValidation(fElement);
+ lfm.disableValidation(fNewElement);
+
+ return new RenameLibraryFolderChange(fNewElement, fElement);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/messages.properties b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/messages.properties
new file mode 100644
index 0000000..ec5c57c
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/core/libfolders/messages.properties
@@ -0,0 +1 @@
+RenameLibraryFolderChange_name=Continue using ''{0}'' as a library folder
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/PHPCorePlugin.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/PHPCorePlugin.java
index af017bb..8f27452 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/PHPCorePlugin.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/PHPCorePlugin.java
@@ -25,6 +25,7 @@ import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.internal.core.ModelManager;
import org.eclipse.dltk.internal.core.search.ProjectIndexerManager;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
import org.eclipse.php.internal.core.includepath.IncludePathManager;
import org.eclipse.php.internal.core.model.PhpModelAccess;
import org.eclipse.php.internal.core.project.PHPNature;
@@ -77,6 +78,9 @@ public class PHPCorePlugin extends Plugin {
// start the include path manager
IncludePathManager.getInstance();
+ // start the library folder manager
+ LibraryFolderManager.getInstance();
+
// register the listener in charge of converting the projects -
// applies for projects being opened during work
ResourcesPlugin.getWorkspace().addResourceChangeListener(
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/builder/ParserBuildParticipantFactory.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/builder/ParserBuildParticipantFactory.java
index 7e5de5d..f6d92c5 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/builder/ParserBuildParticipantFactory.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/builder/ParserBuildParticipantFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 xored software, Inc.
+ * Copyright (c) 2008, 2014 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ * Zend Technologies - [424340] Library Folders (Kaloyan Raev)
*******************************************************************************/
package org.eclipse.php.internal.core.builder;
@@ -19,15 +20,14 @@ import org.eclipse.dltk.ast.parser.IModuleDeclaration;
import org.eclipse.dltk.ast.parser.ISourceParser;
import org.eclipse.dltk.compiler.env.IModuleSource;
import org.eclipse.dltk.compiler.problem.ProblemCollector;
-import org.eclipse.dltk.core.DLTKLanguageManager;
-import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.core.*;
import org.eclipse.dltk.core.ISourceModuleInfoCache.ISourceModuleInfo;
-import org.eclipse.dltk.core.SourceParserUtil;
import org.eclipse.dltk.core.builder.AbstractBuildParticipantType;
import org.eclipse.dltk.core.builder.IBuildContext;
import org.eclipse.dltk.core.builder.IBuildParticipant;
import org.eclipse.dltk.core.builder.IScriptBuilder;
import org.eclipse.dltk.internal.core.ModelManager;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
public class ParserBuildParticipantFactory extends AbstractBuildParticipantType
implements IExecutableExtension {
@@ -61,6 +61,12 @@ public class ParserBuildParticipantFactory extends AbstractBuildParticipantType
}
public void build(IBuildContext context) throws CoreException {
+ IModelElement element = context.getModelElement();
+ if (LibraryFolderManager.getInstance().isInLibraryFolder(element)) {
+ // skip syntax check for code inside library folders
+ return;
+ }
+
IModuleDeclaration moduleDeclaration = (ModuleDeclaration) context
.get(IBuildContext.ATTR_MODULE_DECLARATION);
if (moduleDeclaration != null) {
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderJob.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderJob.java
new file mode 100644
index 0000000..72a9089
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderJob.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.core.libfolders;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.*;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.php.core.libfolders.ILibraryFolderNameProvider;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.wst.validation.internal.PrefConstants;
+import org.eclipse.wst.validation.internal.PreferencesWrapper;
+
+/**
+ * A workspace job for automatically detecting library folders in a given array
+ * of projects.
+ *
+ * <p>
+ * The job consults the library folder name providers registered in the
+ * <code>org.eclipse.php.core.libraryFolderNameProviders</code> extension point
+ * for finding the source folders to be marked as library folders.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ */
+public class AutoDetectLibraryFolderJob extends WorkspaceJob {
+
+ private static final String EXTENSION_POINT_ID = "org.eclipse.php.core.libraryFolderNameProviders"; //$NON-NLS-1$
+ private static final String CLASS_ATTR = "class"; //$NON-NLS-1$
+
+ private IProject[] fProjects;
+
+ /**
+ * Constructor for the job.
+ *
+ * @param projects
+ * an array of projects
+ */
+ public AutoDetectLibraryFolderJob(IProject[] projects) {
+ super(Messages.AutoDetectLibraryFolderJob_Name);
+ fProjects = projects;
+ }
+
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor)
+ throws CoreException {
+
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+
+ for (IProject project : fProjects) {
+ // check if the user has already marked any folders as library
+ // folders or source folders
+ if (!hasDisabledPreference(project)) {
+ // check the extension point for common library folder names
+ String[] names = getCommonLibraryFolderNames(project);
+
+ // find these folders in the project
+ IModelElement[] folders = getFoldersFromNames(project, names);
+
+ // mark the folders as library folders
+ try {
+ lfm.useAsLibraryFolder(folders, monitor);
+ } catch (Exception e) {
+ return new Status(IStatus.ERROR, PHPCorePlugin.ID,
+ e.getLocalizedMessage(), e);
+ }
+ }
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Returns whether the given project has the "disabled" preference available
+ * in its WTP Validation Framework preference file.
+ *
+ * @param project
+ * a project
+ *
+ * @return <code>true</code> if the "disable" preference is available, and
+ * <code>false</code> otherwise.
+ */
+ @SuppressWarnings("restriction")
+ private boolean hasDisabledPreference(IProject project) {
+ PreferencesWrapper prefs = PreferencesWrapper.getPreferences(project,
+ null);
+ return prefs.get(PrefConstants.disabled, null) != null;
+ }
+
+ /**
+ * Returns the common library folder names by consulting the library folder
+ * name providers registered in the extension point.
+ *
+ * @param project
+ * a project
+ *
+ * @return an array of folder names
+ */
+ private String[] getCommonLibraryFolderNames(IProject project) {
+ Collection<String> result = new HashSet<String>();
+
+ IConfigurationElement[] elements = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor(EXTENSION_POINT_ID);
+
+ for (IConfigurationElement element : elements) {
+ try {
+ Object o = element.createExecutableExtension(CLASS_ATTR);
+ if (o instanceof ILibraryFolderNameProvider) {
+ ILibraryFolderNameProvider extension = (ILibraryFolderNameProvider) o;
+ String[] names = extension.getLibraryFolderNames(project);
+ if (names != null) {
+ result.addAll(Arrays.asList(names));
+ }
+ }
+ } catch (Exception e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Converts the given array of folder names to an array of model elements
+ * representing them in the given project.
+ *
+ * <p>
+ * A folder name is converted to a model element only if it represents an
+ * existing folder in the given project.
+ * </p>
+ *
+ * @param project
+ * a project
+ * @param folderNames
+ * an array of folder names
+ *
+ * @return an array of model elements
+ */
+ private IModelElement[] getFoldersFromNames(IProject project,
+ String[] folderNames) {
+ Collection<IModelElement> result = new HashSet<IModelElement>();
+
+ for (String name : folderNames) {
+ IModelElement folder = DLTKCore.create(project.getFolder(name));
+ if (folder.exists()) {
+ result.add(folder);
+ }
+ }
+
+ return result.toArray(new IModelElement[result.size()]);
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderListener.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderListener.java
new file mode 100644
index 0000000..81596e2
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/AutoDetectLibraryFolderListener.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.core.libfolders;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+
+/**
+ * A resource change listener that automatically marks source folders as library
+ * folders based on predefined set of rules.
+ *
+ * @author Kaloyan Raev
+ */
+public class AutoDetectLibraryFolderListener implements IResourceChangeListener {
+
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getType() != IResourceChangeEvent.POST_CHANGE)
+ return;
+
+ IResourceDelta delta = event.getDelta();
+
+ // find all projects in the delta that may potentially have folders to
+ // be marked as library folders
+ IProject[] projects = new OpenedAndChangedProjectsFinder(delta)
+ .getFoundProjects();
+
+ // schedule a workspace job to process the projects
+ new AutoDetectLibraryFolderJob(projects).schedule();
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/LibraryFolderRenameParticipant.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/LibraryFolderRenameParticipant.java
new file mode 100644
index 0000000..757bd37
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/LibraryFolderRenameParticipant.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.core.libfolders;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.php.core.libfolders.RenameLibraryFolderChange;
+
+/**
+ * A rename participant that watches if a topmost library folder is renamed.
+ *
+ * @author Kaloyan Raev
+ */
+public class LibraryFolderRenameParticipant extends RenameParticipant {
+
+ /**
+ * The model element of the renamed library folder.
+ */
+ private IModelElement fElement;
+
+ @Override
+ public RefactoringStatus checkConditions(IProgressMonitor monitor,
+ CheckConditionsContext context) throws OperationCanceledException {
+ return new RefactoringStatus();
+ }
+
+ @Override
+ public Change createChange(IProgressMonitor monitor) throws CoreException,
+ OperationCanceledException {
+ IProject project = fElement.getScriptProject().getProject();
+
+ String newName = getArguments().getNewName();
+ IModelElement newElement = DLTKCore.create(project.getFolder(newName));
+
+ return new RenameLibraryFolderChange(fElement, newElement);
+ }
+
+ @Override
+ public String getName() {
+ // not displayed anywhere
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ protected boolean initialize(Object element) {
+ if (!(element instanceof IModelElement))
+ return false;
+
+ fElement = (IModelElement) element;
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+
+ // the participant takes place only if the model element is a topmost
+ // library folder, i.e. it is explicitly disabled in the WTP Validation
+ // Framework
+ return lfm.isTopmostLibraryFolder(fElement);
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/Messages.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/Messages.java
new file mode 100644
index 0000000..18abe2e
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/Messages.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.core.libfolders;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Kaloyan Raev
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.php.internal.core.libfolders.messages"; //$NON-NLS-1$
+ public static String AutoDetectLibraryFolderJob_Name;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/OpenedAndChangedProjectsFinder.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/OpenedAndChangedProjectsFinder.java
new file mode 100644
index 0000000..a63b312
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/OpenedAndChangedProjectsFinder.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.core.libfolders;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.php.internal.core.PHPCorePlugin;
+import org.eclipse.php.internal.core.project.PHPNature;
+
+/**
+ * A resource delta visitor that finds in a resource delta all project that are
+ * opened or have a new folder added.
+ *
+ * @author Kaloyan Raev
+ */
+public class OpenedAndChangedProjectsFinder implements IResourceDeltaVisitor {
+
+ private IResourceDelta fDelta;
+
+ private Collection<IProject> fFoundProjects;
+
+ /**
+ * Creates a new finder for the given resource delta.
+ *
+ * @param delta
+ * a resource delta
+ */
+ public OpenedAndChangedProjectsFinder(IResourceDelta delta) {
+ fDelta = delta;
+ }
+
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ IResource resource = delta.getResource();
+ if (resource == null)
+ return false;
+
+ switch (resource.getType()) {
+ case IResource.ROOT:
+ return visitWorkspaceRoot(delta);
+ case IResource.PROJECT:
+ return visitProject(delta);
+ case IResource.FOLDER:
+ return visitFolder(delta);
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns all found projects in the resource delta.
+ *
+ * @return an array of projects
+ */
+ public IProject[] getFoundProjects() {
+ if (fFoundProjects == null) {
+ fFoundProjects = new HashSet<IProject>();
+ try {
+ fDelta.accept(this);
+ } catch (CoreException e) {
+ PHPCorePlugin.log(e);
+ }
+ }
+
+ return fFoundProjects.toArray(new IProject[fFoundProjects.size()]);
+ }
+
+ private boolean visitWorkspaceRoot(IResourceDelta delta) {
+ return delta.getKind() == IResourceDelta.CHANGED;
+ }
+
+ private boolean visitProject(IResourceDelta delta) throws CoreException {
+ if ((delta.getFlags() & (IResourceDelta.OPEN | IResourceDelta.DESCRIPTION)) == 0)
+ // visit project folders
+ return true;
+
+ IProject project = (IProject) delta.getResource();
+ if (!project.isOpen())
+ // the project is closed
+ return false;
+
+ if (!project.hasNature(PHPNature.ID))
+ // not a PHP project
+ return false;
+
+ // add the project to found projects
+ fFoundProjects.add(project);
+
+ // no need to visit project folders
+ return false;
+ }
+
+ private boolean visitFolder(IResourceDelta delta) {
+ if (delta.getKind() == IResourceDelta.ADDED) {
+ // add folder's project to found projects
+ IProject project = delta.getResource().getProject();
+ fFoundProjects.add(project);
+
+ // no need to visit subfolders
+ return false;
+ }
+
+ // visit subfolders
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/messages.properties b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/messages.properties
new file mode 100644
index 0000000..90f6b02
--- /dev/null
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/libfolders/messages.properties
@@ -0,0 +1 @@
+AutoDetectLibraryFolderJob_Name=Detecting library folders
diff --git a/plugins/org.eclipse.php.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.php.ui/META-INF/MANIFEST.MF
index bf246da..db8c3a5 100644
--- a/plugins/org.eclipse.php.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.php.ui/META-INF/MANIFEST.MF
@@ -43,7 +43,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.common,
org.eclipse.dltk.core.manipulation,
org.eclipse.wst.common.project.facet.core,
- org.eclipse.wst.common.project.facet.ui
+ org.eclipse.wst.common.project.facet.ui,
+ org.apache.commons.lang
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.php.internal.ui;x-internal:=true,
org.eclipse.php.internal.ui.actions;x-internal:=true,
diff --git a/plugins/org.eclipse.php.ui/icons/full/obj16/libfolder_obj.gif b/plugins/org.eclipse.php.ui/icons/full/obj16/libfolder_obj.gif
new file mode 100644
index 0000000..8d6f7c9
--- /dev/null
+++ b/plugins/org.eclipse.php.ui/icons/full/obj16/libfolder_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java
index 7a22c3b..724ba94 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 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
@@ -30,11 +30,13 @@ import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.templates.ContextTypeRegistry;
import org.eclipse.jface.text.templates.persistence.TemplateStore;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
import org.eclipse.php.internal.core.format.PhpFormatProcessorImpl;
import org.eclipse.php.internal.ui.corext.template.php.CodeTemplateContextType;
import org.eclipse.php.internal.ui.editor.ASTProvider;
import org.eclipse.php.internal.ui.editor.templates.PhpCommentTemplateContextType;
import org.eclipse.php.internal.ui.editor.templates.PhpTemplateContextType;
+import org.eclipse.php.internal.ui.explorer.LibraryFolderChangeListener;
import org.eclipse.php.internal.ui.folding.PHPFoldingStructureProviderRegistry;
import org.eclipse.php.internal.ui.preferences.PHPTemplateStore;
import org.eclipse.php.internal.ui.preferences.PreferenceConstants;
@@ -96,6 +98,7 @@ public class PHPUiPlugin extends AbstractUIPlugin {
private PHPEditorTextHoverDescriptor[] fPHPEditorTextHoverDescriptors;
private PHPManualSiteDescriptor[] fPHPManualSiteDescriptors;
private ImagesOnFileSystemRegistry fImagesOnFSRegistry;
+ private LibraryFolderChangeListener libraryFolderChangeListener;
/**
* The AST provider.
@@ -141,6 +144,10 @@ public class PHPUiPlugin extends AbstractUIPlugin {
Job job = new Job("") { //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
+ libraryFolderChangeListener = new LibraryFolderChangeListener();
+ LibraryFolderManager.getInstance().addListener(
+ libraryFolderChangeListener);
+
PlatformUI.getWorkbench().getDisplay()
.asyncExec(new Runnable() {
public void run() {
@@ -214,6 +221,13 @@ public class PHPUiPlugin extends AbstractUIPlugin {
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
+
+ if (libraryFolderChangeListener != null) {
+ LibraryFolderManager.getInstance().removeListener(
+ libraryFolderChangeListener);
+ libraryFolderChangeListener = null;
+ }
+
Platform.getJobManager().cancel(OPEN_TYPE_HIERARCHY_ACTION_FAMILY_NAME);
Platform.getJobManager().cancel(OPEN_CALL_HIERARCHY_ACTION_FAMILY_NAME);
fASTProvider = null;
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/LibraryFolderActionGroup.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/LibraryFolderActionGroup.java
new file mode 100644
index 0000000..eb113c1
--- /dev/null
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/LibraryFolderActionGroup.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.ui.actions;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.ui.IContextMenuConstants;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.actions.ActionGroup;
+
+/**
+ * An action group that contributes the "Use As Library Folder" and
+ * "Use As Source Folder" actions in the PHP Explorer's context menu.
+ *
+ * @author Kaloyan Raev
+ */
+public class LibraryFolderActionGroup extends ActionGroup {
+
+ private IWorkbenchSite fSite;
+
+ public LibraryFolderActionGroup(IViewPart part) {
+ fSite = part.getSite();
+ }
+
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+
+ IAction action = getActionFromSelection();
+ if (action != null) {
+ menu.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, action);
+ }
+ }
+
+ /**
+ * Returns the action to add to context menu based on the current selection.
+ *
+ * <ul>
+ * <li>If the current selection consists of only source folders then the
+ * "Use As Library Folders" action will be returned</li>
+ * <li>If the current selection consists of only library folders then the
+ * "Use As Source Folders" action will be returned</li>
+ * <li>In all other cases, this method returns <code>null</code></li>
+ * </ul>
+ *
+ * @return the action to add to the context menu, or <code>null</code> if no
+ * appropriate action can be determined
+ */
+ private IAction getActionFromSelection() {
+ ISelection sel = fSite.getSelectionProvider().getSelection();
+ if (!(sel instanceof IStructuredSelection))
+ return null;
+
+ IStructuredSelection selection = (IStructuredSelection) sel;
+ Iterator<?> iterator = selection.iterator();
+
+ Collection<IModelElement> selected = new HashSet<IModelElement>();
+
+ // collect all folders from the current selection
+ while (iterator.hasNext()) {
+ Object obj = iterator.next();
+
+ if (!(obj instanceof IModelElement))
+ // the selection contains an object that is not a model element
+ return null;
+
+ IModelElement element = (IModelElement) obj;
+ IResource resource = element.getResource();
+
+ if (resource == null)
+ // the selection contains a model element without a
+ // corresponding resource on the file system
+ return null;
+
+ if (resource.getType() != IResource.FOLDER)
+ // the selection contains a model element that is not a folder
+ return null;
+
+ selected.add(element);
+ }
+
+ IModelElement[] elements = selected.toArray(new IModelElement[selected
+ .size()]);
+
+ if (elements.length == 0)
+ // no folders in the selection
+ return null;
+
+ if (!allOfSameKind(elements))
+ // a mixture of source folders and library folders in the selection
+ return null;
+
+ if (LibraryFolderManager.getInstance().isInLibraryFolder(elements[0])) {
+ // the selection contains only library folders
+ return new UseAsSourceFolderAction(fSite, elements);
+ } else {
+ // the selection contains only source folders
+ return new UseAsLibraryFolderAction(elements);
+ }
+ }
+
+ /**
+ * Returns whether the given model elements are either all library folders
+ * or all source folders.
+ *
+ * <p>
+ * It is assumed that all given model elements are folders.
+ * </p>
+ *
+ * @param elements
+ * an array of model elements
+ *
+ * @return <code>true</code> if the given model elements are either all
+ * library folders or source folder, and <code>false</code>
+ * otherwise
+ */
+ private boolean allOfSameKind(IModelElement[] elements) {
+ int libraryFolderCount = 0;
+
+ // count the library folders in the array
+ for (IModelElement element : elements) {
+ if (LibraryFolderManager.getInstance().isInLibraryFolder(element)) {
+ libraryFolderCount++;
+ }
+ }
+
+ // If the number of library folders is 0, then all elements are source
+ // folders. If the number of library folders equals the number of given
+ // elements, then all elements are library folders. In any other case,
+ // there is a mixture of library folders and source folders.
+ return libraryFolderCount == 0 || libraryFolderCount == elements.length;
+ }
+}
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/Messages.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/Messages.java
index 56d5a3a..5246f10 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/Messages.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/Messages.java
@@ -13,6 +13,10 @@ public class Messages extends NLS {
public static String SelectionHandler_0;
public static String DeleteAction_0;
public static String GenerateIncludePathActionGroup_0;
+ public static String LibraryFolderAction_Dialog_description;
+ public static String LibraryFolderAction_Dialog_title;
+ public static String LibraryFolderAction_UseAsLibraryFolder_label;
+ public static String LibraryFolderAction_UseAsSourceFolder_label;
public static String OpenTypeHierarchyAction_0;
public static String OpenTypeHierarchyAction_3;
public static String OpenCallHierarchyAction_0;
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/PHPExplorerActionGroup.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/PHPExplorerActionGroup.java
index 6c57fc2..54db61e 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/PHPExplorerActionGroup.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/PHPExplorerActionGroup.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 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
@@ -122,6 +122,7 @@ public class PHPExplorerActionGroup extends ScriptExplorerActionGroup {
phpRefactorActionGroup = new PHPRefactorActionGroup(getPart());
filtered.add(phpRefactorActionGroup);
filtered.add(new GenerateIncludePathActionGroup(getPart()));
+ filtered.add(new LibraryFolderActionGroup(getPart()));
filtered.add(new NamespaceGroupingActionGroup(getPart().getTreeViewer()));
filtered.add(new PHPFileOperationActionGroup(getPart()));
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsLibraryFolderAction.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsLibraryFolderAction.java
new file mode 100644
index 0000000..852b053
--- /dev/null
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsLibraryFolderAction.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.jface.action.Action;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.php.internal.ui.PHPUiPlugin;
+import org.eclipse.php.internal.ui.util.PHPPluginImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+
+/**
+ * Represents the "Use As Library Folder" in the PHP Explorer's context menu.
+ *
+ * <p>
+ * This action executes the
+ * {@link LibraryFolderManager#useAsLibraryFolder(IModelElement[], IProgressMonitor)}
+ * method in a {@link WorkspaceModifyOperation}.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ */
+public class UseAsLibraryFolderAction extends Action {
+
+ /**
+ * The array of model elements (i.e. source folders) to mark as library
+ * folders.
+ */
+ private IModelElement[] fElements;
+
+ /**
+ * Constructor a new "Use As Library Folder" action to mark the given source
+ * folders as library folders.
+ *
+ * @param elements
+ * an array of model elements to mark as library folders
+ */
+ public UseAsLibraryFolderAction(IModelElement[] elements) {
+ if (elements.length == 0)
+ throw new IllegalArgumentException("empty elements array");
+
+ fElements = elements;
+
+ setText(Messages.LibraryFolderAction_UseAsLibraryFolder_label);
+ setImageDescriptor(PHPPluginImages.DESC_OBJS_PHP_LIBFOLDER);
+ }
+
+ @Override
+ public void run() {
+ // execute the action in a WorkspaceModifyOperation to batch the
+ // resource change events and avoid unnecessary triggering build jobs
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+ @Override
+ protected void execute(IProgressMonitor monitor)
+ throws CoreException, InvocationTargetException,
+ InterruptedException {
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+ lfm.useAsLibraryFolder(fElements, monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
+ } catch (Exception e) {
+ PHPUiPlugin.log(e);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsSourceFolderAction.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsSourceFolderAction.java
new file mode 100644
index 0000000..31e20f7
--- /dev/null
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/UseAsSourceFolderAction.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.php.internal.ui.PHPUiPlugin;
+import org.eclipse.php.internal.ui.util.PHPPluginImages;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+
+/**
+ * Represents the "Use As Source Folder" in the PHP Explorer's context menu.
+ *
+ * <p>
+ * This action executes the
+ * {@link LibraryFolderManager#useAsSourceFolder(IModelElement[], IProgressMonitor)}
+ * method in a {@link WorkspaceModifyOperation}.
+ * </p>
+ *
+ * @author Kaloyan Raev
+ */
+public class UseAsSourceFolderAction extends Action {
+
+ /**
+ * Reference to the workbench site.
+ */
+ private IWorkbenchSite fSite;
+
+ /**
+ * The array of model elements (i.e. library folders) to mark as source
+ * folders.
+ */
+ private IModelElement[] fElements;
+
+ /**
+ * Constructor a new "Use As Source Folder" action to mark the given library
+ * folders as source folders.
+ *
+ * @param site
+ * a reference to the workbench site
+ * @param elements
+ * an array of model elements to mark as source folders
+ */
+ public UseAsSourceFolderAction(IWorkbenchSite site, IModelElement[] elements) {
+ if (elements.length == 0)
+ throw new IllegalArgumentException("empty elements array");
+
+ fSite = site;
+ fElements = elements;
+
+ setText(Messages.LibraryFolderAction_UseAsSourceFolder_label);
+ setImageDescriptor(PHPPluginImages.DESC_OBJS_PHPFOLDER_ROOT);
+ }
+
+ @Override
+ public void run() {
+ boolean askForConfirmation = false;
+ Collection<IModelElement> topmostElements = new HashSet<IModelElement>();
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+
+ // check if any of the selected library folders is not a topmost library
+ // folder
+ for (IModelElement element : fElements) {
+ IModelElement topmostLibraryFolder = lfm
+ .getTopmostLibraryFolder(element);
+ topmostElements.add(topmostLibraryFolder);
+
+ if (!element.equals(topmostLibraryFolder)) {
+ // there is a selected folder which is not a topmost library
+ // folder, so ask the user for confirmation to mark the topmost
+ // library folder as source folder
+ askForConfirmation = true;
+ }
+ }
+
+ final IModelElement[] elements = topmostElements
+ .toArray(new IModelElement[topmostElements.size()]);
+
+ if (askForConfirmation) {
+ // show the confirmation dialog
+ String title = Messages.LibraryFolderAction_Dialog_title;
+ String message = NLS.bind(
+ Messages.LibraryFolderAction_Dialog_description,
+ StringUtils.join(getSortedElementNames(elements), ",\n\t"));
+
+ if (!MessageDialog.openConfirm(fSite.getShell(), title, message))
+ // the user clicked the Cancel button - abort the action
+ return;
+ }
+
+ // execute the action in a WorkspaceModifyOperation to batch the
+ // resource change events and avoid unnecessary triggering build jobs
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+ @Override
+ protected void execute(IProgressMonitor monitor)
+ throws CoreException, InvocationTargetException,
+ InterruptedException {
+ LibraryFolderManager.getInstance().useAsSourceFolder(elements,
+ monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
+ } catch (Exception e) {
+ PHPUiPlugin.log(e);
+ }
+
+ }
+
+ /**
+ * Returns the names of the given model elements in sorted order.
+ *
+ * @param elements
+ * an array of model elements
+ *
+ * @return a sorted array of strings with the names of the given model
+ * elements
+ */
+ private String[] getSortedElementNames(IModelElement[] elements) {
+ String[] names = new String[elements.length];
+
+ for (int i = 0; i < elements.length; i++) {
+ names[i] = elements[i].getElementName();
+ }
+
+ Arrays.sort(names);
+
+ return names;
+ }
+
+}
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/messages.properties b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/messages.properties
index 8adb303..ebac190 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/messages.properties
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/actions/messages.properties
@@ -8,6 +8,10 @@ ReorgMoveAction_1=A resource with the same name exists in the target folder.
SelectionHandler_0=Error trying to resolve document's element
DeleteAction_0=Add help support here...
GenerateIncludePathActionGroup_0=Add help support here...
+LibraryFolderAction_Dialog_description=One or more of the selected folders are not topmost library folders in the file tree. Library folders cannot contain source folders. The following topmost library folders will be turned to source folders:\n\n\t{0}
+LibraryFolderAction_Dialog_title=Use As Source Folder
+LibraryFolderAction_UseAsLibraryFolder_label=Use As Library Folder
+LibraryFolderAction_UseAsSourceFolder_label=Use As Source Folder
OpenTypeHierarchyAction_0=Open &Type Hierarchy
OpenTypeHierarchyAction_3=A PHP element must be selected.
RemoveFromIncludepathAction_0=Remove from Include Path \ No newline at end of file
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/LibraryFolderChangeListener.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/LibraryFolderChangeListener.java
new file mode 100644
index 0000000..c42a8a2
--- /dev/null
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/LibraryFolderChangeListener.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Zend Technologies 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:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.php.internal.ui.explorer;
+
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.php.core.libfolders.ILibraryFolderChangeListener;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
+import org.eclipse.php.internal.ui.PHPUiPlugin;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.*;
+
+/**
+ * A library folder change listener that updates the images of the given folders
+ * and all their subfolders in the PHP Explorer whenever a source folder is
+ * turned to library folder and vice versa.
+ *
+ * @author Kaloyan Raev
+ */
+public class LibraryFolderChangeListener implements
+ ILibraryFolderChangeListener {
+
+ public void folderChanged(IModelElement[] elements) {
+ try {
+ updatePhpExplorer(elements);
+ } catch (ModelException e) {
+ PHPUiPlugin.log(e);
+ }
+ }
+
+ /**
+ * Updates the visual state of the given model elements and all their
+ * children in the PHP Explorer view.
+ *
+ * @param elements
+ * an array of model elements to update
+ *
+ * @throws ModelException
+ * if any of the given element does not exist or if an exception
+ * occurs while accessing its corresponding resource
+ */
+ private void updatePhpExplorer(IModelElement[] elements)
+ throws ModelException {
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+ final IModelElement[] subfolders = lfm.getAllSubfolders(elements);
+
+ // make sure the actual update in the PHP Explorer is executed in the UI
+ // thread
+ Display.getDefault().asyncExec(new Runnable() {
+ @SuppressWarnings("restriction")
+ public void run() {
+ final PHPExplorerPart phpExplorer = getPhpExplorer();
+ if (phpExplorer != null) {
+ phpExplorer.getTreeViewer().update(subfolders, null);
+ }
+ }
+ });
+ }
+
+ /**
+ * Returns a reference to the PHP Explorer view part.
+ *
+ * @return a reference to {@link PHPExplorerPart}, or <code>null</code> if
+ * none is available in the active workbench page
+ */
+ private PHPExplorerPart getPhpExplorer() {
+ // find the active workbench window
+ IWorkbenchWindow window = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow();
+ if (window == null)
+ return null;
+
+ // find the active workbench page
+ IWorkbenchPage page = window.getActivePage();
+ if (page == null)
+ return null;
+
+ // find the PHP Explorer in all available view references
+ for (IWorkbenchPartReference ref : page.getViewReferences()) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null && part instanceof PHPExplorerPart) {
+ return (PHPExplorerPart) part;
+ }
+ }
+
+ // the PHP Explorer view is not found
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/PHPExplorerLabelProvider.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/PHPExplorerLabelProvider.java
index 566205e..d7f1679 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/PHPExplorerLabelProvider.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/explorer/PHPExplorerLabelProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 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
@@ -23,6 +23,7 @@ import org.eclipse.dltk.internal.ui.navigator.ScriptExplorerLabelProvider;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.php.core.compiler.PHPFlags;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
import org.eclipse.php.internal.core.includepath.IncludePath;
import org.eclipse.php.internal.core.language.LanguageModelInitializer;
import org.eclipse.php.internal.ui.util.LabelProviderUtil;
@@ -112,10 +113,19 @@ public class PHPExplorerLabelProvider extends ScriptExplorerLabelProvider {
return PHPPluginImages
.get(PHPPluginImages.IMG_OBJS_PHP_FOLDER);
} else {// in build path ...
- if (modelElement.getElementType() == IModelElement.SCRIPT_FOLDER
- || element instanceof IFolder)
- return PHPPluginImages
- .get(PHPPluginImages.IMG_OBJS_PHPFOLDER_ROOT);
+ if (modelElement.getElementType() == IModelElement.PROJECT_FRAGMENT
+ || modelElement.getElementType() == IModelElement.SCRIPT_FOLDER
+ || element instanceof IFolder) {
+ LibraryFolderManager lfm = LibraryFolderManager
+ .getInstance();
+ if (lfm.isInLibraryFolder(modelElement)) {
+ return PHPPluginImages
+ .get(PHPPluginImages.IMG_OBJS_PHP_LIBFOLDER);
+ } else {
+ return PHPPluginImages
+ .get(PHPPluginImages.IMG_OBJS_PHPFOLDER_ROOT);
+ }
+ }
}
}
try {
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/preferences/includepath/PHPIPListLabelProvider.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/preferences/includepath/PHPIPListLabelProvider.java
index a833a0f..38b1dd6 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/preferences/includepath/PHPIPListLabelProvider.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/preferences/includepath/PHPIPListLabelProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 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
@@ -24,6 +24,7 @@ import org.eclipse.dltk.ui.ScriptElementImageDescriptor;
import org.eclipse.dltk.ui.ScriptElementImageProvider;
import org.eclipse.dltk.ui.viewsupport.ImageDescriptorRegistry;
import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.php.core.libfolders.LibraryFolderManager;
import org.eclipse.php.internal.ui.phar.wizard.PharUIUtil;
import org.eclipse.php.internal.ui.util.LabelProviderUtil;
import org.eclipse.php.internal.ui.util.PHPPluginImages;
@@ -93,8 +94,13 @@ public class PHPIPListLabelProvider extends BPListLabelProvider {
IModelElement modelElement = DLTKCore.create(resource);
if (null != modelElement) {
- if (modelElement instanceof IScriptFolder)
- return PHPPluginImages.DESC_OBJS_PHPFOLDER_ROOT;
+ if (modelElement instanceof IScriptFolder) {
+ LibraryFolderManager lfm = LibraryFolderManager.getInstance();
+ if (lfm.isInLibraryFolder(modelElement))
+ return PHPPluginImages.DESC_OBJS_PHP_LIBFOLDER;
+ else
+ return PHPPluginImages.DESC_OBJS_PHPFOLDER_ROOT;
+ }
} else {
return PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
diff --git a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/util/PHPPluginImages.java b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/util/PHPPluginImages.java
index 8d674a0..c1055a7 100644
--- a/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/util/PHPPluginImages.java
+++ b/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/util/PHPPluginImages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 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
@@ -101,6 +101,8 @@ public class PHPPluginImages {
+ "folderroot_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJS_MISSING_PHPFOLDER_ROOT = NAME_PREFIX
+ "folderroot_nonexist_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_PHP_LIBFOLDER = NAME_PREFIX
+ + "libfolder_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJS_PHP_MODEL = NAME_PREFIX
+ "script_model_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJS_UNKNOWN = NAME_PREFIX
@@ -175,6 +177,8 @@ public class PHPPluginImages {
T_OBJ, IMG_OBJS_PHPFOLDER_ROOT);
public static final ImageDescriptor DESC_OBJS_MISSING_PHPFOLDER_ROOT = createManaged(
T_OBJ, IMG_OBJS_MISSING_PHPFOLDER_ROOT);
+ public static final ImageDescriptor DESC_OBJS_PHP_LIBFOLDER = createManaged(
+ T_OBJ, IMG_OBJS_PHP_LIBFOLDER);
public static final ImageDescriptor DESC_OBJS_PHP_MODEL = createManaged(
T_OBJ, IMG_OBJS_PHP_MODEL);
public static final ImageDescriptor DESC_OBJ_PHP_CLASSES_GROUP = createManaged(
@@ -221,13 +225,13 @@ public class PHPPluginImages {
public static final ImageDescriptor DESC_OVR_DEPRECATED = create(T_OVR,
"deprecated.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OVR_CONSTANT = create(T_OVR,
- "constant_co.gif"); //$NON-NLS-1$
+ "constant_co.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OVR_ABSTRACT = create(T_OVR,
- "abstract_co.gif"); //$NON-NLS-1$
+ "abstract_co.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OVR_FINAL = create(T_OVR,
- "final_co.gif"); //$NON-NLS-1$
+ "final_co.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OVR_STATIC = create(T_OVR,
- "static_co.gif"); //$NON-NLS-1$
+ "static_co.gif"); //$NON-NLS-1$
public static final ImageDescriptor DESC_OBJS_ZIP = createManaged(T_OBJ,
IMG_OBJS_ZIP);
@@ -350,8 +354,8 @@ public class PHPPluginImages {
/*
* try { ImageDescriptor id=
* ImageDescriptor.createFromURL(makeIconFileURL("c" + type, relPath));
- * if (id != null) action.setHoverImageDescriptor(id); }
- * catch (MalformedURLException e) { }
+ * if (id != null) action.setHoverImageDescriptor(id); } catch
+ * (MalformedURLException e) { }
*/
ImageDescriptor descriptor = create("e" + type, relPath); //$NON-NLS-1$