Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 301601
Collapse All | Expand All

(-)META-INF/MANIFEST.MF (+1 lines)
Lines 10-15 Link Here
10
 org.eclipse.jst.common.jdt.internal.classpath;x-internal:=true,
10
 org.eclipse.jst.common.jdt.internal.classpath;x-internal:=true,
11
 org.eclipse.jst.common.jdt.internal.integration;x-internal:=true,
11
 org.eclipse.jst.common.jdt.internal.integration;x-internal:=true,
12
 org.eclipse.jst.common.jdt.internal.javalite,
12
 org.eclipse.jst.common.jdt.internal.javalite,
13
 org.eclipse.jst.common.modulecore,
13
 org.eclipse.jst.common.project.facet
14
 org.eclipse.jst.common.project.facet
14
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
15
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
15
 org.eclipse.jdt.core;bundle-version="[3.2.0,4.0.0)",
16
 org.eclipse.jdt.core;bundle-version="[3.2.0,4.0.0)",
(-)src/org/eclipse/jst/common/modulecore/ISingleRootStatus.java (+54 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.common.modulecore;
12
13
import org.eclipse.core.resources.IContainer;
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.core.runtime.IStatus;
16
17
public interface ISingleRootStatus extends IStatus {
18
	
19
	// Information [0-32] 
20
	public static final int SINGLE_ROOT_CONTAINER_FOUND = 1;
21
	public static final int SINGLE_ROOT_FORCED = 2;
22
	//DO NOT ADD ANY OTHER CONSTANTS TO THE INFORMATION SECTION
23
	
24
	// Warnings [33-127]
25
	public static final int SOURCE_PATH_NOT_FOUND = 33;
26
	
27
	// Errors [128-512]
28
	public static final int NO_COMPONENT_FOUND = 67;
29
	public static final int EXPLICITLY_DISABLED = 68;
30
	public static final int CONSUMABLE_REFERENCES_FOUND = 69;
31
	public static final int LINKED_RESOURCES_FOUND = 70;
32
	public static final int NO_RESOURCE_MAPS_FOUND = 71;
33
	public static final int JAVA_OUTPUT_NOT_A_CONTENT_ROOT = 72;
34
	public static final int JAVA_OUTPUT_GREATER_THAN_1 = 73;
35
	public static final int RUNTIME_PATH_NOT_ROOT = 74;
36
	public static final int SOURCE_NOT_JAVA_CONTAINER = 75;
37
38
	// callback-contributed errors: 128-anything
39
	
40
	/**
41
	 * Returns the path with which the status is associated.
42
	 *
43
	 * @return the path with which the status is associated.
44
	 */
45
	public IPath getPath();
46
	
47
	/** 
48
	 * Will return the IContainer that is used as the "single-root".
49
	 * If a "single-root" structure is not found this method will return null. 
50
	 * 
51
	 * @return the "single-root" container
52
	 */ 
53
	public IContainer getSingleRoot();
54
}
(-)src/org/eclipse/jst/common/modulecore/SingleRootExportParticipant.java (+139 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 Red Hat and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Red Hat - Initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.common.modulecore;
12
13
import java.util.ArrayList;
14
import java.util.List;
15
16
import org.eclipse.core.resources.IContainer;
17
import org.eclipse.core.resources.IFile;
18
import org.eclipse.core.resources.IResource;
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.jst.common.modulecore.SingleRootUtil.SingleRootCallback;
23
import org.eclipse.wst.common.componentcore.internal.flat.AbstractFlattenParticipant;
24
import org.eclipse.wst.common.componentcore.internal.flat.FlatFolder;
25
import org.eclipse.wst.common.componentcore.internal.flat.FlatResource;
26
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFile;
27
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFolder;
28
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
29
import org.eclipse.wst.common.componentcore.internal.flat.IFlattenParticipant;
30
import org.eclipse.wst.common.componentcore.internal.flat.VirtualComponentFlattenUtility;
31
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
32
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
33
34
/**
35
 * Single root optimization. 
36
 * @author rob
37
 */
38
public class SingleRootExportParticipant extends AbstractFlattenParticipant {
39
	private SingleRootParticipantCallback callbackHandler;
40
	private IVirtualComponent rootComponent;
41
	private FlatComponentTaskModel dataModel;
42
	
43
	public interface SingleRootParticipantCallback extends SingleRootCallback {
44
		public IFlattenParticipant[] getDelegateParticipants();
45
	}
46
	
47
	public SingleRootExportParticipant() {
48
		super();
49
		callbackHandler = null;
50
	}
51
	public SingleRootExportParticipant(SingleRootParticipantCallback handler) {
52
		this();
53
		callbackHandler = handler;
54
	}
55
	
56
	@Override
57
	public void initialize(IVirtualComponent component,
58
			FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
59
		this.rootComponent = component;
60
		this.dataModel = dataModel;
61
	}
62
63
64
	@Override
65
	public boolean canOptimize(IVirtualComponent component,
66
			FlatComponentTaskModel dataModel) {
67
		return new SingleRootUtil(component, callbackHandler).isSingleRoot();
68
	}
69
70
	@Override
71
	public void optimize(IVirtualComponent component,
72
			FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
73
		try {
74
			resources.clear(); // We want complete control
75
			IContainer container = new SingleRootUtil(component).getSingleRoot();
76
			IFlatResource[] mr = getMembers(resources, container, new Path("")); //$NON-NLS-1$
77
			int size = mr.length;
78
			for (int j = 0; j < size; j++) {
79
				resources.add(mr[j]);
80
			}
81
			
82
			// run finalizers
83
			IFlattenParticipant[] delegates = callbackHandler.getDelegateParticipants();
84
			for(int i = 0; i < delegates.length; i++ ) {
85
				delegates[i].finalize(component, dataModel, resources);
86
			}
87
		} catch( CoreException ce ) {
88
			// TODO 
89
		}
90
	}
91
92
	protected IFlatResource[] getMembers(List<IFlatResource> members, 
93
			IContainer cont, IPath path) throws CoreException {
94
		IResource[] res = cont.members();
95
		int size2 = res.length;
96
		List list = new ArrayList(size2);
97
		for (int j = 0; j < size2; j++) {
98
			if (res[j] instanceof IContainer) {
99
				IContainer cc = (IContainer) res[j];
100
				// Retrieve already existing module folder if applicable
101
				IFlatFolder mf = (FlatFolder) VirtualComponentFlattenUtility.getExistingModuleResource(members,path.append(new Path(cc.getName()).makeRelative()));
102
				if (mf == null) {
103
					mf = new FlatFolder(cc, cc.getName(), path);
104
					IFlatFolder parent = (FlatFolder) VirtualComponentFlattenUtility.getExistingModuleResource(members, path);
105
					if (path.isEmpty() || path.equals(new Path("/"))) //$NON-NLS-1$
106
						members.add(mf);
107
					else {
108
						if (parent == null)
109
							parent = VirtualComponentFlattenUtility.ensureParentExists(members, path, cc);
110
						VirtualComponentFlattenUtility.addMembersToModuleFolder(parent, new IFlatResource[] {mf});
111
					}
112
				}
113
				IFlatResource[] mr = getMembers(members, cc, path.append(cc.getName()));
114
				VirtualComponentFlattenUtility.addMembersToModuleFolder(mf, mr);
115
			} else {
116
				IFile f = (IFile) res[j];
117
				IFlatFile mf = VirtualComponentFlattenUtility.createModuleFile(f, path);
118
				if( shouldAddExportableFile(rootComponent, rootComponent, dataModel, mf))
119
					list.add(mf);
120
			}
121
		}
122
		FlatResource[] mr = new FlatResource[list.size()];
123
		list.toArray(mr);
124
		return mr;
125
	}
126
	
127
	@Override
128
	public boolean shouldAddExportableFile(IVirtualComponent rootComponent,
129
			IVirtualComponent currentComponent, FlatComponentTaskModel dataModel,
130
			IFlatFile file) {
131
		IFlattenParticipant[] delegates = callbackHandler.getDelegateParticipants();
132
		for(int i = 0; i < delegates.length; i++ ) {
133
			if( !delegates[i].shouldAddExportableFile(rootComponent, currentComponent, dataModel, file))
134
				return false;
135
		}
136
		return true;
137
	}
138
139
}
(-)src/org/eclipse/jst/common/modulecore/SingleRootStatus.java (+48 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.common.modulecore;
12
13
import org.eclipse.core.resources.IContainer;
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.core.runtime.IStatus;
16
import org.eclipse.core.runtime.Status;
17
import org.eclipse.jst.common.frameworks.CommonFrameworksPlugin;
18
19
public class SingleRootStatus extends Status implements ISingleRootStatus {
20
21
	IPath path;
22
	IContainer container;
23
24
	public SingleRootStatus(int type, int code, IPath resourcePath, IContainer containerPath, String message, Throwable exception) {
25
		super(type, CommonFrameworksPlugin.PLUGIN_ID, code, message, exception);
26
		path = resourcePath;
27
		container = containerPath;
28
	}
29
	
30
	public SingleRootStatus(int code, IPath resourcePath, IContainer containerPath) {
31
		this(getSeverity(code), code, resourcePath, containerPath, null, null);
32
	}
33
	
34
	public IPath getPath() {
35
		return path;
36
	}
37
38
	public IContainer getSingleRoot() {
39
		return container;
40
	}
41
	
42
	protected static int getSeverity(int code) {
43
		if( code < 33 ) return IStatus.INFO;
44
		if( code < 128 ) return IStatus.WARNING;
45
		return IStatus.ERROR;
46
	}
47
48
}
(-)src/org/eclipse/jst/common/modulecore/SingleRootUtil.java (+443 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.common.modulecore;
12
13
import java.util.Collections;
14
import java.util.Iterator;
15
import java.util.List;
16
17
import org.eclipse.core.resources.IContainer;
18
import org.eclipse.core.resources.IFolder;
19
import org.eclipse.core.resources.IProject;
20
import org.eclipse.core.resources.IResource;
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IPath;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.MultiStatus;
25
import org.eclipse.core.runtime.Path;
26
import org.eclipse.core.runtime.Status;
27
import org.eclipse.jst.common.frameworks.CommonFrameworksPlugin;
28
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
29
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
30
import org.eclipse.wst.common.componentcore.internal.Property;
31
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
32
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
33
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
34
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
35
36
public class SingleRootUtil {
37
	public interface SingleRootCallback {
38
		public boolean canValidate(IProject project);
39
		public void validate(SingleRootUtil util, IVirtualComponent vc, IProject project, List resourceMaps);
40
	}
41
	
42
	/** 
43
	 * Used to return immediately after the first error code is found.
44
	 */
45
	public static final int INCLUDE_FIRST_ERROR = 0x08;
46
	/** 
47
	 * Used to capture all status codes (error, warning, info)
48
	 */
49
	public static final int INCLUDE_ALL = 0x07;
50
	/** 
51
	 * Used to capture all error and warning status codes only.
52
	 */
53
	public static final int INCLUDE_ERRORS_AND_WARNINGS = 0x06;
54
	/** 
55
	 * Used to capture all error status codes only.
56
	 */
57
	public static final int INCLUDE_ERRORS = 0x04;
58
	
59
	private static final int WARNINGS = 0x02;
60
	private static final int INFO = 0x01;
61
	private static final int CANCEL = 0x0;
62
	private static final int GET_SINGLE_ROOT_CONTAINER = 0x09;
63
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
64
	private IVirtualComponent aComponent;
65
	private SingleRootCallback callback;
66
	private List<IContainer> cachedSourceContainers;
67
	private IContainer[] cachedOutputContainers;
68
	private MultiStatus wrapperStatus;
69
	private int VALIDATE_FLAG;
70
	
71
	public SingleRootUtil(IVirtualComponent component) {
72
		this(component, null);
73
	}
74
75
	public SingleRootUtil(IVirtualComponent component, SingleRootCallback callback) {
76
		this.aComponent = component;
77
		this.callback = callback;
78
	}
79
	
80
81
	/**
82
	 * Returns true if this module has a simple structure based on a
83
	 * single-root folder, and false otherwise.
84
     *
85
	 * In a single-root structure, all files that are contained within the root folder
86
	 * are part of the module, and are already in the correct module structure. No
87
	 * module resources exist outside of this single folder.
88
	 * 
89
	 * @return true if this module has a single-root structure, and
90
	 *         false otherwise
91
	 */
92
	public boolean isSingleRoot() {
93
		return validateSingleRoot(INCLUDE_FIRST_ERROR).getSeverity() != IStatus.ERROR;
94
	}
95
	
96
	/**
97
	 * Will attempt to return the IContainer that counts as the "single-root".
98
	 * If this module does not qualify as a "single-root" module, this
99
	 * method will return null. Otherwise it will return an IContainer
100
	 * that may be used as the single-root container. 
101
	 * 
102
	 * @return IContainer representing single-root container
103
	 */
104
	public IContainer getSingleRoot() {
105
		IStatus status = validateSingleRoot(GET_SINGLE_ROOT_CONTAINER);
106
		if (status.getSeverity() == IStatus.INFO) {
107
			IStatus[] children = ((MultiStatus) status).getChildren();
108
			ISingleRootStatus rootStatus = (ISingleRootStatus) children[0];
109
			return rootStatus.getSingleRoot();
110
		}
111
		return null;	
112
	}
113
114
	/**
115
	 *  Validates whether the component module has a single-root structure.
116
	 *  An IStatus with a severity of OK is returned for a valid single-root 
117
	 *  structure.  A MultiStatus containing children of type ISingleRootStatus
118
	 *  is returned if any status codes were captured during the validation.
119
	 *  A MultiStatus with a severity of INFO or WARNING is returned for a valid 
120
	 *  single-root structure containing status codes with no severities of ERROR.
121
	 *  A MultiStatus with a severity of ERROR means the component does not have a
122
	 *  valid single-root structure.
123
	 *  
124
	 * @param flag - indicates the status codes (by severity) to capture during
125
	 *               the validation.  The INLCUDE_ALL flag will also capture the 
126
	 *               single-root container if a single-root structure was found.
127
	 *               Valid flags are: 
128
	 *               				  INCLUDE_ALL
129
	 *                                INCLUDE_ERRORS_AND_WARNINGS
130
	 *                                INCLUDE_ERRORS
131
	 *                                INCLUDE_FIRST_ERROR
132
	 *               
133
	 * @return IStatus
134
	 */
135
	public IStatus validateSingleRoot(int flag) {
136
		VALIDATE_FLAG = flag;
137
		wrapperStatus = null;
138
		StructureEdit edit = null;
139
		try {
140
			edit = StructureEdit.getStructureEditForRead(getProject());
141
			if (edit == null || edit.getComponent() == null) {
142
				reportStatus(ISingleRootStatus.NO_COMPONENT_FOUND);
143
				return getStatus();
144
			}	
145
			
146
			// 229650 - check to see if the property 'useSingleRoot' is defined. 
147
			Boolean useSingleRoot = getUseSingleRootProperty(edit);
148
			if (useSingleRoot != null) {
149
				//check if it was set to false
150
				if (!useSingleRoot.booleanValue()) {
151
					reportStatus(ISingleRootStatus.EXPLICITLY_DISABLED);
152
				}
153
				else {
154
					reportStatus(ISingleRootStatus.SINGLE_ROOT_FORCED, aComponent.getRootFolder().getUnderlyingFolder());
155
				}
156
				return getStatus();
157
			}
158
			
159
			// if there are any consumed references, this is not single-root
160
			if (hasConsumableReferences(aComponent)) {
161
				reportStatus(ISingleRootStatus.CONSUMABLE_REFERENCES_FOUND);
162
				if (VALIDATE_FLAG == CANCEL)
163
					return getStatus();
164
			}
165
			
166
			// if there are any linked resources then this is not a single-root module
167
			if (rootFoldersHaveLinkedContent()) {
168
				reportStatus(ISingleRootStatus.LINKED_RESOURCES_FOUND);
169
				if (VALIDATE_FLAG == CANCEL) 
170
					return getStatus();
171
			}
172
			
173
			List resourceMaps = edit.getComponent().getResources();
174
			
175
			// If the list is empty, return false
176
			if (resourceMaps.size() < 1) {
177
				reportStatus(ISingleRootStatus.NO_RESOURCE_MAPS_FOUND);
178
				return getStatus();
179
			}
180
			
181
			if (resourceMaps.size() == 1) {
182
				ComponentResource mapping = (ComponentResource)resourceMaps.get(0); 
183
				if (isRootMapping(mapping)) {
184
					IResource sourceResource = getProject().findMember(mapping.getSourcePath());
185
					if (sourceResource != null && sourceResource.exists()) {
186
						if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
187
							reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, (IContainer) sourceResource);
188
							return getStatus();
189
						}
190
					}
191
				}
192
			}
193
			
194
			if( callback != null && callback.canValidate(getProject())) { 
195
				callback.validate(this, aComponent, getProject(), resourceMaps);
196
			} else {
197
				validateProject(resourceMaps);
198
			}
199
			return getStatus();
200
		} finally {
201
			cachedOutputContainers = null;
202
			cachedSourceContainers = null;
203
			if (edit != null)
204
				edit.dispose();
205
		}
206
	}
207
	
208
	protected Boolean getUseSingleRootProperty(StructureEdit edit) {
209
		WorkbenchComponent wbComp = edit.getComponent();
210
		final List componentProperties = wbComp.getProperties();
211
		if (componentProperties != null) {
212
			final Iterator componentPropertiesIterator = componentProperties.iterator();
213
			while (componentPropertiesIterator.hasNext()) {
214
				Property wbProperty = (Property) componentPropertiesIterator.next();
215
				if (USE_SINGLE_ROOT_PROPERTY.equals(wbProperty.getName())) {
216
					return Boolean.valueOf(wbProperty.getValue());
217
				}
218
			}
219
		}
220
		return null;
221
	}
222
	
223
	protected boolean hasConsumableReferences(IVirtualComponent vc) {
224
		IVirtualReference[] refComponents = vc.getReferences();
225
    	for (int i = 0; i < refComponents.length; i++) {
226
    		IVirtualReference reference = refComponents[i];
227
    		if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
228
    			return true;
229
    		}
230
    	}
231
    	return false;
232
    }
233
234
	private void validateProject(List resourceMaps) {
235
		// Ensure there are only source folder component resource mappings to the root content folder
236
		if (isRootResourceMapping(resourceMaps)) {
237
			IContainer[] javaOutputFolders = getJavaOutputFolders();
238
			// Verify only one java outputfolder
239
			if (javaOutputFolders.length == 1) {
240
				// By the time we get here we know: for any folders defined as source in the 
241
				// .component file that they are also java source folders.
242
				if (!isSourceContainer(javaOutputFolders[0])) {
243
					// The single output folder is NOT a source folder so this is single-rooted. Since the
244
					// output folder (something like classes or bin) is not a source folder, JDT copies all files
245
					// (including non Java files) to this folder, so every resource needed at runtime is located 
246
					// in a single directory.
247
					reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, javaOutputFolders[0]);
248
					return;
249
				} 
250
				// Verify the java output folder is the same as one of the content roots
251
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
252
				IContainer[] rootFolders = aComponent.getRootFolder().getUnderlyingFolders();
253
				for (int i=0; i < rootFolders.length; i++) {
254
					IPath compRootPath = rootFolders[i].getProjectRelativePath();
255
					if (javaOutputPath.equals(compRootPath)) {
256
						reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, aComponent.getRootFolder().getUnderlyingFolder());
257
						return;
258
					}
259
				}
260
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_A_CONTENT_ROOT);
261
			}
262
			else {
263
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
264
			}
265
		}
266
	}
267
268
	public IContainer[] getJavaOutputFolders() {
269
		if (cachedOutputContainers == null)
270
			cachedOutputContainers = getJavaOutputFolders(aComponent);
271
		return cachedOutputContainers;
272
	}
273
	
274
	public static IContainer[] getJavaOutputFolders(IVirtualComponent component) {
275
		if (component == null)
276
			return new IContainer[0];
277
		
278
		List<IContainer> l = JavaLiteUtilities.getJavaOutputContainers(component);
279
		return l.toArray(new IContainer[l.size()]);
280
	}	
281
	
282
	/**
283
	 * Checks if the path argument is to a source container for the project.
284
	 * 
285
	 * @param a workspace relative full path
286
	 * @return is path a source container?
287
	 */
288
	public boolean isSourceContainer(IContainer sourceContainer) {
289
		if (cachedSourceContainers == null) {
290
			cachedSourceContainers = getSourceContainers(aComponent);
291
		}
292
		return cachedSourceContainers.contains(sourceContainer);
293
	}
294
	
295
	public static List<IContainer> getSourceContainers(IVirtualComponent component) {
296
		if (component == null)
297
			Collections.emptyList();
298
		return JavaLiteUtilities.getJavaSourceContainers(component);
299
	}	
300
	
301
	/*
302
     * This method returns true if the root folders of this component have any linked resources (folder or file);
303
     * Otherwise false is returned.
304
     */
305
    private boolean rootFoldersHaveLinkedContent() {
306
    	if (this.aComponent != null) {
307
    		final IContainer[] rootFolders = this.aComponent.getRootFolder().getUnderlyingFolders();
308
    		for (int i = 0; i < rootFolders.length; i++) {
309
    			try {
310
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
311
    				if (hasLinkedContent) {
312
    					return true;
313
    				}
314
    			}
315
    			catch (CoreException coreEx) {
316
    				CommonFrameworksPlugin.logError(coreEx);
317
    			}
318
    		}
319
    	}
320
    	return false;
321
    }
322
    
323
    /*
324
     * If the resource to check is a file then this method will return true if the file is linked. If the resource to
325
     * check is a folder then this method will return true if it, any of its sub directories, or any file contained
326
     * with-in this directory of any of it's sub directories are linked. Otherwise false is returned.
327
     */
328
    private boolean hasLinkedContent(final IResource resourceToCheck) throws CoreException {
329
    	if ((resourceToCheck != null) && resourceToCheck.isAccessible()) {
330
    		// skip non-accessible files
331
    		if (resourceToCheck.isLinked()) {
332
    			return true;
333
    		}
334
    		switch (resourceToCheck.getType()) {
335
    			case IResource.FOLDER:
336
    				// recursively check sub directory contents
337
    				final IResource[] subDirContents = ((IFolder) resourceToCheck).members();
338
    				for (int i = 0; i < subDirContents.length; i++) {
339
    					if (hasLinkedContent(subDirContents[i])) {
340
    						return true;
341
    					}
342
    				}
343
    				break;
344
    			case IResource.FILE:
345
    				return resourceToCheck.isLinked();
346
    			default:
347
    				// skip as we only care about files and folders
348
    				break;
349
    		}
350
    	}
351
    	return false;
352
    }
353
    
354
    /**
355
	 * Ensure that any component resource mappings are for source folders and 
356
	 * that they map to the root content folder
357
	 * 
358
	 * @param resourceMaps
359
	 * @return boolean
360
	 */
361
	private boolean isRootResourceMapping(List resourceMaps) {
362
		for (int i=0; i < resourceMaps.size(); i++) {
363
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
364
			// Verify it maps to "/" for the content root
365
			if (!isRootMapping(resourceMap)) {
366
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT, resourceMap.getRuntimePath());
367
				if (VALIDATE_FLAG == CANCEL) return false;
368
			}
369
			
370
			// verify it is also a src container
371
			IPath sourcePath = resourceMap.getSourcePath();
372
			IResource sourceResource = getProject().findMember(sourcePath);
373
			if (sourceResource != null && sourceResource.exists()) {
374
				if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
375
					reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
376
				}
377
			}
378
			else {
379
				reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
380
			}
381
			if (VALIDATE_FLAG == CANCEL) return false;
382
		}
383
		return true;
384
	}
385
	
386
	public boolean isRootMapping(ComponentResource map) {
387
		// Verify it maps to "/" for the content root
388
		if (map.getRuntimePath().equals(Path.ROOT))
389
			return true;
390
		return false;
391
	}
392
		
393
	public IProject getProject() {
394
		return aComponent.getProject();
395
	}
396
397
	public void reportStatus(int code) {
398
		reportStatus(code, null, null);
399
	}
400
	
401
	public void reportStatus(int code, IContainer container) {
402
		reportStatus(code, null, container);
403
	}
404
	
405
	public void reportStatus(int code, IPath path) {
406
		reportStatus(code, path, null);
407
	}
408
	
409
	public void reportStatus(int code, IPath path, IContainer container) {
410
		ISingleRootStatus status = new SingleRootStatus(code, path, container);
411
		if (status.getSeverity() == IStatus.ERROR) {
412
			if ((VALIDATE_FLAG & INCLUDE_FIRST_ERROR) != 0) {
413
				VALIDATE_FLAG = CANCEL;
414
				addStatus(status);
415
			}
416
			else if ((VALIDATE_FLAG & INCLUDE_ERRORS) != 0) {
417
				addStatus(status);
418
			}
419
		}
420
		else if (status.getSeverity() == IStatus.WARNING && (VALIDATE_FLAG & WARNINGS) != 0) {
421
			addStatus(status);
422
		}
423
		else if (status.getSeverity() == IStatus.INFO && (VALIDATE_FLAG & INFO) != 0) { 
424
			addStatus(status);
425
		}
426
	}
427
428
	public IStatus getStatus() {
429
		if (wrapperStatus != null) {
430
			return wrapperStatus;
431
		}
432
		return Status.OK_STATUS;
433
	}
434
435
	private void addStatus(ISingleRootStatus status) {
436
		if (wrapperStatus == null) {
437
			wrapperStatus = new MultiStatus(CommonFrameworksPlugin.PLUGIN_ID, 0, new IStatus[] { status }, null, null);
438
		} else {
439
			wrapperStatus.add(status);
440
		}
441
	}
442
	
443
}
(-)archiveops/org/eclipse/jst/j2ee/internal/archive/ComponentArchiveLoadAdapter.java (-2 / +3 lines)
Lines 39-44 Link Here
39
import org.eclipse.jdt.core.IJavaProject;
39
import org.eclipse.jdt.core.IJavaProject;
40
import org.eclipse.jdt.core.IPackageFragmentRoot;
40
import org.eclipse.jdt.core.IPackageFragmentRoot;
41
import org.eclipse.jdt.core.JavaCore;
41
import org.eclipse.jdt.core.JavaCore;
42
import org.eclipse.jst.common.modulecore.SingleRootUtil;
42
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
43
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
43
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
44
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
44
import org.eclipse.jst.j2ee.internal.J2EEConstants;
45
import org.eclipse.jst.j2ee.internal.J2EEConstants;
Lines 47-53 Link Here
47
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
48
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
48
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
49
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
49
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
50
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
50
import org.eclipse.jst.j2ee.project.SingleRootUtil;
51
import org.eclipse.jst.j2ee.project.JavaEESingleRootCallback;
51
import org.eclipse.jst.jee.archive.AbstractArchiveLoadAdapter;
52
import org.eclipse.jst.jee.archive.AbstractArchiveLoadAdapter;
52
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
53
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
53
import org.eclipse.jst.jee.archive.IArchive;
54
import org.eclipse.jst.jee.archive.IArchive;
Lines 312-318 Link Here
312
	}
313
	}
313
314
314
	protected void attemptOptimization() {
315
	protected void attemptOptimization() {
315
		SingleRootUtil util = new SingleRootUtil(getComponent());
316
		SingleRootUtil util = new SingleRootUtil(getComponent(), new JavaEESingleRootCallback());
316
		IContainer rootContainer = util.getSingleRoot();
317
		IContainer rootContainer = util.getSingleRoot();
317
		if (rootContainer != null) {
318
		if (rootContainer != null) {
318
			try {
319
			try {
(-)common/org/eclipse/jst/j2ee/internal/common/exportmodel/SingleRootExportParticipant.java (-130 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 Red Hat and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Red Hat - Initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.j2ee.internal.common.exportmodel;
12
13
import java.util.ArrayList;
14
import java.util.List;
15
import java.util.Map;
16
17
import org.eclipse.core.resources.IContainer;
18
import org.eclipse.core.resources.IFile;
19
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.IPath;
22
import org.eclipse.core.runtime.Path;
23
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
24
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
25
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType;
26
import org.eclipse.jst.j2ee.project.SingleRootUtil;
27
import org.eclipse.wst.common.componentcore.internal.flat.AbstractFlattenParticipant;
28
import org.eclipse.wst.common.componentcore.internal.flat.VirtualComponentFlattenUtility;
29
import org.eclipse.wst.common.componentcore.internal.flat.FlatFile;
30
import org.eclipse.wst.common.componentcore.internal.flat.FlatFolder;
31
import org.eclipse.wst.common.componentcore.internal.flat.FlatResource;
32
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFolder;
33
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
34
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
35
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
36
37
/**
38
 * Single root optimization. 
39
 * @author rob
40
 */
41
public class SingleRootExportParticipant extends AbstractFlattenParticipant {
42
	private IVirtualComponent component;
43
	private FlatComponentTaskModel dataModel;
44
	private ReplaceManifestExportParticipant manifestReplacementDelegate;
45
	
46
	@Override
47
	public void initialize(IVirtualComponent component,
48
			FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
49
		this.component = component;
50
		this.dataModel = dataModel;
51
	}
52
53
54
	@Override
55
	public boolean canOptimize(IVirtualComponent component,
56
			FlatComponentTaskModel dataModel) {
57
		return new SingleRootUtil(component).isSingleRoot() && !hasClasspathDependencies(component);
58
	}
59
	
60
	protected boolean hasClasspathDependencies(IVirtualComponent component) {
61
		try {
62
			final Map entriesToAttrib = ClasspathDependencyUtil.getRawComponentClasspathDependencies(
63
					JavaCoreLite.create(component.getProject()), 
64
					DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
65
			return entriesToAttrib != null && entriesToAttrib.size() > 0;
66
		} catch( CoreException ce ) {}
67
		return false;
68
	}
69
70
	@Override
71
	public void optimize(IVirtualComponent component,
72
			FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
73
		manifestReplacementDelegate = new ReplaceManifestExportParticipant();
74
		
75
		try {
76
			resources.clear(); // We want complete control
77
			IContainer container = new SingleRootUtil(component).getSingleRoot();
78
			IFlatResource[] mr = getMembers(resources, container, new Path("")); //$NON-NLS-1$
79
			int size = mr.length;
80
			for (int j = 0; j < size; j++) {
81
				resources.add(mr[j]);
82
			}
83
			manifestReplacementDelegate.forceUpdate(component, dataModel, resources);
84
		} catch( CoreException ce ) {
85
			// TODO 
86
		}
87
	}
88
89
	protected IFlatResource[] getMembers(List<IFlatResource> members, 
90
			IContainer cont, IPath path) throws CoreException {
91
		IResource[] res = cont.members();
92
		int size2 = res.length;
93
		List list = new ArrayList(size2);
94
		for (int j = 0; j < size2; j++) {
95
			if (res[j] instanceof IContainer) {
96
				IContainer cc = (IContainer) res[j];
97
				// Retrieve already existing module folder if applicable
98
				IFlatFolder mf = (FlatFolder) VirtualComponentFlattenUtility.getExistingModuleResource(members,path.append(new Path(cc.getName()).makeRelative()));
99
				if (mf == null) {
100
					mf = new FlatFolder(cc, cc.getName(), path);
101
					IFlatFolder parent = (FlatFolder) VirtualComponentFlattenUtility.getExistingModuleResource(members, path);
102
					if (path.isEmpty() || path.equals(new Path("/"))) //$NON-NLS-1$
103
						members.add(mf);
104
					else {
105
						if (parent == null)
106
							parent = VirtualComponentFlattenUtility.ensureParentExists(members, path, cc);
107
						VirtualComponentFlattenUtility.addMembersToModuleFolder(parent, new IFlatResource[] {mf});
108
					}
109
				}
110
				IFlatResource[] mr = getMembers(members, cc, path.append(cc.getName()));
111
				VirtualComponentFlattenUtility.addMembersToModuleFolder(mf, mr);
112
			} else {
113
				IFile f = (IFile) res[j];
114
				FlatFile mf = VirtualComponentFlattenUtility.createModuleFile(f, path);
115
				if (shouldAddComponentFile(mf)) {
116
					list.add(mf);
117
				}
118
			}
119
		}
120
		FlatResource[] mr = new FlatResource[list.size()];
121
		list.toArray(mr);
122
		return mr;
123
	}
124
	
125
	// checking solely for manifest file
126
	protected boolean shouldAddComponentFile(FlatFile file) {
127
		return manifestReplacementDelegate.shouldAddExportableFile(component, component, dataModel, file);
128
	}
129
	
130
}
(-)j2eecreation/org/eclipse/jst/j2ee/internal/project/SingleRootStatus.java (-46 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.j2ee.internal.project;
12
13
import org.eclipse.core.resources.IContainer;
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.core.runtime.Status;
16
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
17
import org.eclipse.jst.j2ee.project.ISingleRootStatus;
18
19
public class SingleRootStatus extends Status implements ISingleRootStatus {
20
21
	IPath path;
22
	IContainer container;
23
24
	public SingleRootStatus(int type, int code, IPath resourcePath, IContainer containerPath, String message, Throwable exception) {
25
		super(type, J2EEPlugin.PLUGIN_ID, code, message, exception);
26
		path = resourcePath;
27
		container = containerPath;
28
	}
29
	
30
	public SingleRootStatus(int code, IPath resourcePath, IContainer containerPath) {
31
		this(getSeverity(code), code, resourcePath, containerPath, null, null);
32
	}
33
	
34
	public IPath getPath() {
35
		return path;
36
	}
37
38
	public IContainer getSingleRoot() {
39
		return container;
40
	}
41
	
42
	protected static int getSeverity(int code) {
43
		return code == 0 ? 0 : 1 << (code / 33);
44
	}
45
46
}
(-)j2eecreation/org/eclipse/jst/j2ee/project/ISingleRootStatus.java (-77 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.j2ee.project;
12
13
import org.eclipse.core.resources.IContainer;
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.core.runtime.IStatus;
16
17
public interface ISingleRootStatus extends IStatus {
18
	
19
	// Information [0-32] 
20
	public static final int SINGLE_ROOT_CONTAINER_FOUND = 1;
21
	public static final int SINGLE_ROOT_FORCED = 2;
22
	//DO NOT ADD ANY OTHER CONSTANTS TO THE INFORMATION SECTION
23
	
24
	// Warnings [33-65]
25
	public static final int SOURCE_PATH_NOT_FOUND = 33;
26
	
27
	// Errors [66-98]
28
	public static final int NO_COMPONENT_FOUND = 67;
29
30
	public static final int JAVA_OUTPUT_GREATER_THAN_1 = 68;
31
32
	public static final int EAR_PROJECT_FOUND = 69;
33
34
	public static final int LINKED_RESOURCES_FOUND = 70;
35
36
	public static final int JAVA_OUTPUT_NOT_A_CONTENT_ROOT = 71;
37
38
	public static final int JAVA_OUTPUT_NOT_WEBINF_CLASSES = 72;
39
40
	public static final int ATLEAST_1_RESOURCE_MAP_MISSING = 73;
41
42
	public static final int NO_RESOURCE_MAPS_FOUND = 74;
43
44
	public static final int ONE_CONTENT_ROOT_REQUIRED = 75;
45
46
	public static final int ATLEAST_1_JAVA_SOURCE_REQUIRED = 76;
47
48
	public static final int RUNTIME_PATH_NOT_ROOT = 77;
49
50
	public static final int SOURCE_NOT_JAVA_CONTAINER = 78;
51
52
	public static final int RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES = 79;
53
54
	public static final int ONLY_1_CONTENT_ROOT_ALLOWED = 80;
55
	
56
	public static final int EXPLICITLY_DISABLED = 81;
57
58
	public static final int CONSUMABLE_REFERENCES_FOUND = 82;
59
60
	
61
	/**
62
	 * Returns the path with which the status is associated.
63
	 *
64
	 * @return the path with which the status is associated.
65
	 */
66
	public IPath getPath();
67
	
68
	/** 
69
	 * Will return the IContainer that is used as the "single-root".
70
	 * If a "single-root" structure is not found this method will return null. 
71
	 * 
72
	 * @return the "single-root" container
73
	 */ 
74
	public IContainer getSingleRoot();
75
76
77
}
(-)j2eecreation/org/eclipse/jst/j2ee/project/JavaEESingleRootCallback.java (+170 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 Red Hat and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Red Hat - Initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.j2ee.project;
12
13
import java.util.List;
14
import java.util.Map;
15
16
import org.eclipse.core.resources.IContainer;
17
import org.eclipse.core.resources.IProject;
18
import org.eclipse.core.resources.IResource;
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
23
import org.eclipse.jst.common.modulecore.ISingleRootStatus;
24
import org.eclipse.jst.common.modulecore.SingleRootUtil;
25
import org.eclipse.jst.common.modulecore.SingleRootExportParticipant.SingleRootParticipantCallback;
26
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
27
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType;
28
import org.eclipse.jst.j2ee.internal.J2EEConstants;
29
import org.eclipse.jst.j2ee.internal.common.exportmodel.ReplaceManifestExportParticipant;
30
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
31
import org.eclipse.wst.common.componentcore.internal.flat.AbstractFlattenParticipant;
32
import org.eclipse.wst.common.componentcore.internal.flat.FilterResourceParticipant;
33
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
34
import org.eclipse.wst.common.componentcore.internal.flat.IFlattenParticipant;
35
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
36
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
37
38
public class JavaEESingleRootCallback implements SingleRootParticipantCallback {
39
	public static final int EAR_PROJECT_FOUND = 10100;
40
	public static final int ATLEAST_1_RESOURCE_MAP_MISSING = 10101;
41
	public static final int JAVA_OUTPUT_NOT_WEBINF_CLASSES = 10102;
42
	public static final int RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES = 10103;
43
	public static final int ONLY_1_CONTENT_ROOT_ALLOWED = 10104;
44
	public static final int ONE_CONTENT_ROOT_REQUIRED = 10105;
45
	public static final int ATLEAST_1_JAVA_SOURCE_REQUIRED = 10106;
46
	public static final int CLASSPATH_DEPENDENCIES_FOUND = 10107;
47
	
48
	public boolean canValidate(IProject project) {
49
		return JavaEEProjectUtilities.isEARProject(project) || 
50
			JavaEEProjectUtilities.isDynamicWebProject(project);
51
	}
52
53
	public void validate(SingleRootUtil util, IVirtualComponent vc, IProject project, List resourceMaps) {
54
		// Always return false for EARs so that members for EAR are always calculated and j2ee modules are filtered out
55
		if (JavaEEProjectUtilities.isEARProject(project)) 
56
			util.reportStatus(EAR_PROJECT_FOUND);
57
58
		//validate web projects for single root
59
		if (JavaEEProjectUtilities.isDynamicWebProject(project)) 
60
			validateWebProject(util, vc, resourceMaps);
61
62
		// If we have classpath dependencies we can't be single root
63
		if( hasClasspathDependencies(vc))
64
			util.reportStatus(CLASSPATH_DEPENDENCIES_FOUND);
65
	}
66
	
67
	protected boolean hasClasspathDependencies(IVirtualComponent component) {
68
		try {
69
			final Map entriesToAttrib = ClasspathDependencyUtil.getRawComponentClasspathDependencies(
70
					JavaCoreLite.create(component.getProject()), 
71
					DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
72
			return entriesToAttrib != null && entriesToAttrib.size() > 0;
73
		} catch( CoreException ce ) {}
74
		return false;
75
	}
76
77
	
78
	private void validateWebProject(SingleRootUtil util, IVirtualComponent vc, List resourceMaps) {
79
		// Ensure there are only basic component resource mappings -- one for the content folder 
80
		// and any for src folders mapped to WEB-INF/classes
81
		if (hasDefaultWebResourceMappings(util, resourceMaps)) {
82
			IContainer[] javaOutputFolders = util.getJavaOutputFolders();
83
			// Verify only one java output folder
84
			if (javaOutputFolders.length == 1) {
85
				// Verify the java output folder is to <content root>/WEB-INF/classes
86
				IPath javaOutputPath = util.getJavaOutputFolders()[0].getProjectRelativePath();
87
				IContainer rootContainer = vc.getRootFolder().getUnderlyingFolder();
88
				IPath compRootPath = rootContainer.getProjectRelativePath();
89
				if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) {
90
					util.reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, rootContainer);
91
					return;
92
				}
93
				util.reportStatus(JAVA_OUTPUT_NOT_WEBINF_CLASSES);
94
			}
95
			else {
96
				util.reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
97
			}
98
		}
99
	}
100
	
101
	/**
102
	 * Ensure the default web setup is correct with one resource map and any number of java 
103
	 * resource maps to WEB-INF/classes
104
	 * 
105
	 * @param resourceMaps
106
	 * @return boolean
107
	 */
108
	private boolean hasDefaultWebResourceMappings(SingleRootUtil util, List resourceMaps) {
109
		int rootValidMaps = 0;
110
		
111
		IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
112
		for (int i = 0; i < resourceMaps.size(); i++) {
113
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
114
			IPath sourcePath = resourceMap.getSourcePath();
115
			IPath runtimePath = resourceMap.getRuntimePath();
116
			IResource sourceResource = util.getProject().findMember(sourcePath);
117
			
118
			// Verify if the map is for the content root
119
			if (util.isRootMapping(resourceMap)) {
120
				rootValidMaps++;
121
			} 
122
			// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
123
			else if (runtimePath.equals(webInfClasses)) {
124
				if (sourceResource != null && sourceResource.exists()) {
125
					if (sourceResource instanceof IContainer && !util.isSourceContainer((IContainer) sourceResource)) {
126
						util.reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
127
						return false;
128
					}
129
				}
130
				else {
131
					util.reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
132
					return false;
133
				}
134
			}
135
			else {
136
				util.reportStatus(RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES, runtimePath);
137
				return false;
138
			}
139
		}
140
		// Make sure only one of the maps is the content root, and that at least one is for the java folder
141
		if (rootValidMaps != 1) {
142
			if (rootValidMaps < 1) {
143
				util.reportStatus(ONE_CONTENT_ROOT_REQUIRED);
144
				return false;
145
			}
146
			else if (rootValidMaps > 1) {
147
				util.reportStatus(ONLY_1_CONTENT_ROOT_ALLOWED);
148
				return false;
149
			}
150
		}
151
		return true;
152
	}
153
154
	public IFlattenParticipant[] getDelegateParticipants() {
155
		return new IFlattenParticipant[] {
156
				createManifestFinalizer(),
157
				FilterResourceParticipant.createSuffixFilterParticipant(new String[]{".java"}) //$NON-NLS-1$
158
		};
159
	}
160
	
161
	public IFlattenParticipant createManifestFinalizer() {
162
		return new AbstractFlattenParticipant() {
163
			@Override
164
			public void finalize(IVirtualComponent component, 
165
					FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
166
				new ReplaceManifestExportParticipant().forceUpdate(component, dataModel, resources);
167
			}
168
		};
169
	}
170
}
(-)j2eecreation/org/eclipse/jst/j2ee/project/SingleRootUtil.java (-517 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jst.j2ee.project;
12
13
import java.util.Collections;
14
import java.util.Iterator;
15
import java.util.List;
16
17
import org.eclipse.core.resources.IContainer;
18
import org.eclipse.core.resources.IFolder;
19
import org.eclipse.core.resources.IProject;
20
import org.eclipse.core.resources.IResource;
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IPath;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.MultiStatus;
25
import org.eclipse.core.runtime.Path;
26
import org.eclipse.core.runtime.Status;
27
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
28
import org.eclipse.jst.j2ee.internal.J2EEConstants;
29
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
30
import org.eclipse.jst.j2ee.internal.project.SingleRootStatus;
31
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
32
import org.eclipse.wst.common.componentcore.internal.Property;
33
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
34
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
35
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
36
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
37
38
public class SingleRootUtil {
39
	
40
	
41
	/** 
42
	 * Used to return immediately after the first error code is found.
43
	 */
44
	public static final int INCLUDE_FIRST_ERROR = 0x08;
45
	/** 
46
	 * Used to capture all status codes (error, warning, info)
47
	 */
48
	public static final int INCLUDE_ALL = 0x07;
49
	/** 
50
	 * Used to capture all error and warning status codes only.
51
	 */
52
	public static final int INCLUDE_ERRORS_AND_WARNINGS = 0x06;
53
	/** 
54
	 * Used to capture all error status codes only.
55
	 */
56
	public static final int INCLUDE_ERRORS = 0x04;
57
	
58
	private static final int WARNINGS = 0x02;
59
	private static final int INFO = 0x01;
60
	private static final int CANCEL = 0x0;
61
	private static final int GET_SINGLE_ROOT_CONTAINER = 0x09;
62
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
63
	private IVirtualComponent aComponent;
64
	private List<IContainer> cachedSourceContainers;
65
	private IContainer[] cachedOutputContainers;
66
	private MultiStatus wrapperStatus;
67
	private int VALIDATE_FLAG;
68
	
69
	public SingleRootUtil(IVirtualComponent component) {
70
		this.aComponent = component;
71
	}
72
	
73
	/**
74
	 * Returns true if this module has a simple structure based on a
75
	 * single-root folder, and false otherwise.
76
     *
77
	 * In a single-root structure, all files that are contained within the root folder
78
	 * are part of the module, and are already in the correct module structure. No
79
	 * module resources exist outside of this single folder.
80
	 * 
81
	 * @return true if this module has a single-root structure, and
82
	 *         false otherwise
83
	 */
84
	public boolean isSingleRoot() {
85
		return validateSingleRoot(INCLUDE_FIRST_ERROR).getSeverity() != IStatus.ERROR;
86
	}
87
	
88
	/**
89
	 * Will attempt to return the IContainer that counts as the "single-root".
90
	 * If this module does not qualify as a "single-root" module, this
91
	 * method will return null. Otherwise it will return an IContainer
92
	 * that may be used as the single-root container. 
93
	 * 
94
	 * @return IContainer representing single-root container
95
	 */
96
	public IContainer getSingleRoot() {
97
		IStatus status = validateSingleRoot(GET_SINGLE_ROOT_CONTAINER);
98
		if (status.getSeverity() == IStatus.INFO) {
99
			IStatus[] children = ((MultiStatus) status).getChildren();
100
			ISingleRootStatus rootStatus = (ISingleRootStatus) children[0];
101
			return rootStatus.getSingleRoot();
102
		}
103
		return null;	
104
	}
105
106
	/**
107
	 *  Validates whether the component module has a single-root structure.
108
	 *  An IStatus with a severity of OK is returned for a valid single-root 
109
	 *  structure.  A MultiStatus containing children of type ISingleRootStatus
110
	 *  is returned if any status codes were captured during the validation.
111
	 *  A MultiStatus with a severity of INFO or WARNING is returned for a valid 
112
	 *  single-root structure containing status codes with no severities of ERROR.
113
	 *  A MultiStatus with a severity of ERROR means the component does not have a
114
	 *  valid single-root structure.
115
	 *  
116
	 * @param flag - indicates the status codes (by severity) to capture during
117
	 *               the validation.  The INLCUDE_ALL flag will also capture the 
118
	 *               single-root container if a single-root structure was found.
119
	 *               Valid flags are: 
120
	 *               				  INCLUDE_ALL
121
	 *                                INCLUDE_ERRORS_AND_WARNINGS
122
	 *                                INCLUDE_ERRORS
123
	 *                                INCLUDE_FIRST_ERROR
124
	 *               
125
	 * @return IStatus
126
	 */
127
	public IStatus validateSingleRoot(int flag) {
128
		VALIDATE_FLAG = flag;
129
		wrapperStatus = null;
130
		StructureEdit edit = null;
131
		try {
132
			edit = StructureEdit.getStructureEditForRead(getProject());
133
			if (edit == null || edit.getComponent() == null) {
134
				reportStatus(ISingleRootStatus.NO_COMPONENT_FOUND);
135
				return getStatus();
136
			}	
137
			
138
			// 229650 - check to see if the property 'useSingleRoot' is defined. 
139
			Boolean useSingleRoot = getUseSingleRootProperty(edit);
140
			if (useSingleRoot != null) {
141
				//check if it was set to false
142
				if (!useSingleRoot.booleanValue()) {
143
					reportStatus(ISingleRootStatus.EXPLICITLY_DISABLED);
144
				}
145
				else {
146
					reportStatus(ISingleRootStatus.SINGLE_ROOT_FORCED, aComponent.getRootFolder().getUnderlyingFolder());
147
				}
148
				return getStatus();
149
			}
150
			
151
			if (JavaEEProjectUtilities.isEARProject(getProject())) {
152
				// Always return false for EARs so that members for EAR are always calculated and j2ee modules are filtered out
153
				reportStatus(ISingleRootStatus.EAR_PROJECT_FOUND);
154
				return getStatus();
155
			}
156
			
157
			// if there are any consumed references, this is not single-root
158
			if (hasConsumableReferences(aComponent)) {
159
				reportStatus(ISingleRootStatus.CONSUMABLE_REFERENCES_FOUND);
160
				if (VALIDATE_FLAG == CANCEL)
161
					return getStatus();
162
			}
163
			
164
			// if there are any linked resources then this is not a single-root module
165
			if (rootFoldersHaveLinkedContent()) {
166
				reportStatus(ISingleRootStatus.LINKED_RESOURCES_FOUND);
167
				if (VALIDATE_FLAG == CANCEL) 
168
					return getStatus();
169
			}
170
			
171
			List resourceMaps = edit.getComponent().getResources();
172
			
173
			// If the list is empty, return false
174
			if (resourceMaps.size() < 1) {
175
				reportStatus(ISingleRootStatus.NO_RESOURCE_MAPS_FOUND);
176
				return getStatus();
177
			}
178
			
179
			if (resourceMaps.size() == 1) {
180
				ComponentResource mapping = (ComponentResource)resourceMaps.get(0); 
181
				if (isRootMapping(mapping)) {
182
					IResource sourceResource = getProject().findMember(mapping.getSourcePath());
183
					if (sourceResource != null && sourceResource.exists()) {
184
						if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
185
							reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, (IContainer) sourceResource);
186
							return getStatus();
187
						}
188
					}
189
				}
190
			}
191
			
192
			if (JavaEEProjectUtilities.isDynamicWebProject(getProject())) {
193
				//validate web projects for single root
194
				validateWebProject(resourceMaps);
195
			} else {
196
				validateProject(resourceMaps);
197
			}
198
			//return the current status
199
			return getStatus();
200
		} finally {
201
			cachedOutputContainers = null;
202
			cachedSourceContainers = null;
203
			if (edit != null)
204
				edit.dispose();
205
		}
206
	}
207
	
208
	protected Boolean getUseSingleRootProperty(StructureEdit edit) {
209
		WorkbenchComponent wbComp = edit.getComponent();
210
		final List componentProperties = wbComp.getProperties();
211
		if (componentProperties != null) {
212
			final Iterator componentPropertiesIterator = componentProperties.iterator();
213
			while (componentPropertiesIterator.hasNext()) {
214
				Property wbProperty = (Property) componentPropertiesIterator.next();
215
				if (USE_SINGLE_ROOT_PROPERTY.equals(wbProperty.getName())) {
216
					return Boolean.valueOf(wbProperty.getValue());
217
				}
218
			}
219
		}
220
		return null;
221
	}
222
	
223
	protected boolean hasConsumableReferences(IVirtualComponent vc) {
224
		IVirtualReference[] refComponents = vc.getReferences();
225
    	for (int i = 0; i < refComponents.length; i++) {
226
    		IVirtualReference reference = refComponents[i];
227
    		if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
228
    			return true;
229
    		}
230
    	}
231
    	return false;
232
    }
233
234
	private void validateProject(List resourceMaps) {
235
		// Ensure there are only source folder component resource mappings to the root content folder
236
		if (isRootResourceMapping(resourceMaps)) {
237
			IContainer[] javaOutputFolders = getJavaOutputFolders();
238
			// Verify only one java outputfolder
239
			if (javaOutputFolders.length == 1) {
240
				// By the time we get here we know: for any folders defined as source in the 
241
				// .component file that they are also java source folders.
242
				if (!isSourceContainer(javaOutputFolders[0])) {
243
					// The single output folder is NOT a source folder so this is single-rooted. Since the
244
					// output folder (something like classes or bin) is not a source folder, JDT copies all files
245
					// (including non Java files) to this folder, so every resource needed at runtime is located 
246
					// in a single directory.
247
					reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, javaOutputFolders[0]);
248
					return;
249
				} 
250
				// Verify the java output folder is the same as one of the content roots
251
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
252
				IContainer[] rootFolders = aComponent.getRootFolder().getUnderlyingFolders();
253
				for (int i=0; i < rootFolders.length; i++) {
254
					IPath compRootPath = rootFolders[i].getProjectRelativePath();
255
					if (javaOutputPath.equals(compRootPath)) {
256
						reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, aComponent.getRootFolder().getUnderlyingFolder());
257
						return;
258
					}
259
				}
260
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_A_CONTENT_ROOT);
261
			}
262
			else {
263
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
264
			}
265
		}
266
	}
267
268
	private void validateWebProject(List resourceMaps) {
269
		// Ensure there are only basic component resource mappings -- one for the content folder 
270
		// and any for src folders mapped to WEB-INF/classes
271
		if (hasDefaultWebResourceMappings(resourceMaps)) {
272
			IContainer[] javaOutputFolders = getJavaOutputFolders();
273
			// Verify only one java output folder
274
			if (javaOutputFolders.length == 1) {
275
				// Verify the java output folder is to <content root>/WEB-INF/classes
276
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
277
				IContainer rootContainer = aComponent.getRootFolder().getUnderlyingFolder();
278
				IPath compRootPath = rootContainer.getProjectRelativePath();
279
				if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) {
280
					reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, rootContainer);
281
					return;
282
				}
283
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_WEBINF_CLASSES);
284
			}
285
			else {
286
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
287
			}
288
		}
289
	}
290
291
	public IContainer[] getJavaOutputFolders() {
292
		if (cachedOutputContainers == null)
293
			cachedOutputContainers = getJavaOutputFolders(aComponent);
294
		return cachedOutputContainers;
295
	}
296
	
297
	public IContainer[] getJavaOutputFolders(IVirtualComponent component) {
298
		if (component == null)
299
			return new IContainer[0];
300
		
301
		List<IContainer> l = JavaLiteUtilities.getJavaOutputContainers(component);
302
		return l.toArray(new IContainer[l.size()]);
303
	}	
304
	
305
	/**
306
	 * Checks if the path argument is to a source container for the project.
307
	 * 
308
	 * @param a workspace relative full path
309
	 * @return is path a source container?
310
	 */
311
	private boolean isSourceContainer(IContainer sourceContainer) {
312
		if (cachedSourceContainers == null) {
313
			cachedSourceContainers = getSourceContainers(aComponent);
314
		}
315
		return cachedSourceContainers.contains(sourceContainer);
316
	}
317
	
318
	public List<IContainer> getSourceContainers(IVirtualComponent component) {
319
		if (component == null)
320
			Collections.emptyList();
321
		
322
		return JavaLiteUtilities.getJavaSourceContainers(component);
323
	}	
324
	
325
	/*
326
     * This method returns true if the root folders of this component have any linked resources (folder or file);
327
     * Otherwise false is returned.
328
     */
329
    private boolean rootFoldersHaveLinkedContent() {
330
    	if (this.aComponent != null) {
331
    		final IContainer[] rootFolders = this.aComponent.getRootFolder().getUnderlyingFolders();
332
    		for (int i = 0; i < rootFolders.length; i++) {
333
    			try {
334
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
335
    				if (hasLinkedContent) {
336
    					return true;
337
    				}
338
    			}
339
    			catch (CoreException coreEx) {
340
    				J2EEPlugin.logError(coreEx);
341
    			}
342
    		}
343
    	}
344
    	return false;
345
    }
346
    
347
    /*
348
     * If the resource to check is a file then this method will return true if the file is linked. If the resource to
349
     * check is a folder then this method will return true if it, any of its sub directories, or any file contained
350
     * with-in this directory of any of it's sub directories are linked. Otherwise false is returned.
351
     */
352
    private boolean hasLinkedContent(final IResource resourceToCheck) throws CoreException {
353
    	if ((resourceToCheck != null) && resourceToCheck.isAccessible()) {
354
    		// skip non-accessible files
355
    		if (resourceToCheck.isLinked()) {
356
    			return true;
357
    		}
358
    		switch (resourceToCheck.getType()) {
359
    			case IResource.FOLDER:
360
    				// recursively check sub directory contents
361
    				final IResource[] subDirContents = ((IFolder) resourceToCheck).members();
362
    				for (int i = 0; i < subDirContents.length; i++) {
363
    					if (hasLinkedContent(subDirContents[i])) {
364
    						return true;
365
    					}
366
    				}
367
    				break;
368
    			case IResource.FILE:
369
    				return resourceToCheck.isLinked();
370
    			default:
371
    				// skip as we only care about files and folders
372
    				break;
373
    		}
374
    	}
375
    	return false;
376
    }
377
    
378
    /**
379
	 * Ensure that any component resource mappings are for source folders and 
380
	 * that they map to the root content folder
381
	 * 
382
	 * @param resourceMaps
383
	 * @return boolean
384
	 */
385
	private boolean isRootResourceMapping(List resourceMaps) {
386
		for (int i=0; i < resourceMaps.size(); i++) {
387
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
388
			// Verify it maps to "/" for the content root
389
			if (!isRootMapping(resourceMap)) {
390
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT, resourceMap.getRuntimePath());
391
				if (VALIDATE_FLAG == CANCEL) return false;
392
			}
393
			
394
			// verify it is also a src container
395
			IPath sourcePath = resourceMap.getSourcePath();
396
			IResource sourceResource = getProject().findMember(sourcePath);
397
			if (sourceResource != null && sourceResource.exists()) {
398
				if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
399
					reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
400
				}
401
			}
402
			else {
403
				reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
404
			}
405
			if (VALIDATE_FLAG == CANCEL) return false;
406
		}
407
		return true;
408
	}
409
	
410
	private boolean isRootMapping(ComponentResource map) {
411
		// Verify it maps to "/" for the content root
412
		if (map.getRuntimePath().equals(Path.ROOT))
413
			return true;
414
		return false;
415
	}
416
	
417
	/**
418
	 * Ensure the default web setup is correct with one resource map and any number of java 
419
	 * resource maps to WEB-INF/classes
420
	 * 
421
	 * @param resourceMaps
422
	 * @return boolean
423
	 */
424
	private boolean hasDefaultWebResourceMappings(List resourceMaps) {
425
		int rootValidMaps = 0;
426
		
427
		IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
428
		for (int i = 0; i < resourceMaps.size(); i++) {
429
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
430
			IPath sourcePath = resourceMap.getSourcePath();
431
			IPath runtimePath = resourceMap.getRuntimePath();
432
			IResource sourceResource = getProject().findMember(sourcePath);
433
			
434
			// Verify if the map is for the content root
435
			if (isRootMapping(resourceMap)) {
436
				rootValidMaps++;
437
			} 
438
			// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
439
			else if (runtimePath.equals(webInfClasses)) {
440
				if (sourceResource != null && sourceResource.exists()) {
441
					if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
442
						reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
443
					}
444
				}
445
				else {
446
					reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
447
				}
448
			}
449
			else {
450
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES, runtimePath);
451
			}
452
			if (VALIDATE_FLAG == CANCEL) return false;
453
		}
454
		// Make sure only one of the maps is the content root, and that at least one is for the java folder
455
		if (rootValidMaps != 1) {
456
			if (rootValidMaps < 1) {
457
				reportStatus(ISingleRootStatus.ONE_CONTENT_ROOT_REQUIRED);
458
			}
459
			else if (rootValidMaps > 1) {
460
				reportStatus(ISingleRootStatus.ONLY_1_CONTENT_ROOT_ALLOWED);
461
			}
462
		}
463
		return VALIDATE_FLAG == CANCEL ? false : true;
464
	}
465
	
466
	private IProject getProject() {
467
		return aComponent.getProject();
468
	}
469
470
	public void reportStatus(int code) {
471
		reportStatus(code, null, null);
472
	}
473
	
474
	public void reportStatus(int code, IContainer container) {
475
		reportStatus(code, null, container);
476
	}
477
	
478
	public void reportStatus(int code, IPath path) {
479
		reportStatus(code, path, null);
480
	}
481
	
482
	public void reportStatus(int code, IPath path, IContainer container) {
483
		ISingleRootStatus status = new SingleRootStatus(code, path, container);
484
		if (status.getSeverity() == IStatus.ERROR) {
485
			if ((VALIDATE_FLAG & INCLUDE_FIRST_ERROR) != 0) {
486
				VALIDATE_FLAG = CANCEL;
487
				addStatus(status);
488
			}
489
			else if ((VALIDATE_FLAG & INCLUDE_ERRORS) != 0) {
490
				addStatus(status);
491
			}
492
		}
493
		else if (status.getSeverity() == IStatus.WARNING && (VALIDATE_FLAG & WARNINGS) != 0) {
494
			addStatus(status);
495
		}
496
		else if (status.getSeverity() == IStatus.INFO && (VALIDATE_FLAG & INFO) != 0) { 
497
			addStatus(status);
498
		}
499
	}
500
501
	public IStatus getStatus() {
502
		if (wrapperStatus != null) {
503
			return wrapperStatus;
504
		}
505
		return Status.OK_STATUS;
506
	}
507
508
	private void addStatus(ISingleRootStatus status) {
509
		if (wrapperStatus == null) {
510
			wrapperStatus = new MultiStatus(J2EEPlugin.PLUGIN_ID, 0, new IStatus[] { status }, null, null);
511
		}
512
		else {
513
			wrapperStatus.add(status);
514
		}
515
	}
516
	
517
}
(-)j2eeplugin/org/eclipse/jst/j2ee/internal/deployables/J2EEFlexProjDeployable.java (-4 / +5 lines)
Lines 22-27 Link Here
22
import org.eclipse.jdt.core.IJavaProject;
22
import org.eclipse.jdt.core.IJavaProject;
23
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
23
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
24
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
24
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
25
import org.eclipse.jst.common.modulecore.SingleRootExportParticipant;
26
import org.eclipse.jst.common.modulecore.SingleRootUtil;
25
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
27
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
26
import org.eclipse.jst.j2ee.ejb.EJBJar;
28
import org.eclipse.jst.j2ee.ejb.EJBJar;
27
import org.eclipse.jst.j2ee.internal.EjbModuleExtensionHelper;
29
import org.eclipse.jst.j2ee.internal.EjbModuleExtensionHelper;
Lines 32-41 Link Here
32
import org.eclipse.jst.j2ee.internal.common.exportmodel.IgnoreJavaInSourceFolderParticipant;
34
import org.eclipse.jst.j2ee.internal.common.exportmodel.IgnoreJavaInSourceFolderParticipant;
33
import org.eclipse.jst.j2ee.internal.common.exportmodel.JEEHeirarchyExportParticipant;
35
import org.eclipse.jst.j2ee.internal.common.exportmodel.JEEHeirarchyExportParticipant;
34
import org.eclipse.jst.j2ee.internal.common.exportmodel.ReplaceManifestExportParticipant;
36
import org.eclipse.jst.j2ee.internal.common.exportmodel.ReplaceManifestExportParticipant;
35
import org.eclipse.jst.j2ee.internal.common.exportmodel.SingleRootExportParticipant;
36
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
37
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
37
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
38
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
38
import org.eclipse.jst.j2ee.project.SingleRootUtil;
39
import org.eclipse.jst.j2ee.project.JavaEESingleRootCallback;
39
import org.eclipse.jst.server.core.IApplicationClientModule;
40
import org.eclipse.jst.server.core.IApplicationClientModule;
40
import org.eclipse.jst.server.core.IConnectorModule;
41
import org.eclipse.jst.server.core.IConnectorModule;
41
import org.eclipse.jst.server.core.IEJBModule;
42
import org.eclipse.jst.server.core.IEJBModule;
Lines 84-96 Link Here
84
	 */
85
	 */
85
	@Override
86
	@Override
86
	public boolean isSingleRootStructure() {
87
	public boolean isSingleRootStructure() {
87
		return new SingleRootUtil(getComponent()).isSingleRoot();
88
		return new SingleRootUtil(getComponent(), new JavaEESingleRootCallback()).isSingleRoot();
88
	}
89
	}
89
	
90
	
90
	@Override
91
	@Override
91
	protected IFlattenParticipant[] getParticipants() {
92
	protected IFlattenParticipant[] getParticipants() {
92
		return new IFlattenParticipant[]{
93
		return new IFlattenParticipant[]{
93
				new SingleRootExportParticipant(), 
94
				new SingleRootExportParticipant(new JavaEESingleRootCallback()), 
94
				new JEEHeirarchyExportParticipant(), 
95
				new JEEHeirarchyExportParticipant(), 
95
				new AddClasspathReferencesParticipant(),
96
				new AddClasspathReferencesParticipant(),
96
				new AddMappedOutputFoldersParticipant(),
97
				new AddMappedOutputFoldersParticipant(),

Return to bug 301601