package org.rubypeople.rdt.internal.core;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.rubypeople.rdt.core.ILoadpathEntry;
import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.util.Util;
public class SourceFolderRootInfo extends OpenableElementInfo {
/**
* A array with all the non-ruby resources contained by this PackageFragment
*/
protected Object[] fNonRubyResources;
/**
* Create and initialize a new instance of the receiver
*/
public SourceFolderRootInfo() {
this.fNonRubyResources = null;
}
/**
* Returns an array of non-ruby resources contained in the receiver.
*/
Object[] getNonRubyResources(IResource underlyingResource) {
if (this.fNonRubyResources == null) {
try {
this.fNonRubyResources =
computeFolderNonRubyResources((IContainer)underlyingResource);
} catch (RubyModelException e) {
// root doesn't exist: consider package has no nonRubyResources
this.fNonRubyResources = NO_NON_RUBY_RESOURCES;
}
}
return this.fNonRubyResources;
}
/**
* Set the nonRubyResources to res value
*/
void setNonRubyResources(Object[] resources) {
this.fNonRubyResources = resources;
}
/**
* Starting at this folder, create non-ruby resources for this package fragment root
* and add them to the non-ruby resources collection.
*
* @exception RubyModelException The resource associated with this package fragment does not exist
*/
static Object[] computeFolderNonRubyResources(IContainer folder) throws RubyModelException {
Object[] nonRubyResources = new IResource[5];
int nonRubyResourcesCounter = 0;
try {
IResource[] members = folder.members();
nextResource: for (int i = 0, max = members.length; i < max; i++) {
IResource member = members[i];
switch (member.getType()) {
case IResource.FILE :
String fileName = member.getName();
// ignore .rb files that are not excluded
if (Util.isValidRubyScriptName(fileName))
continue nextResource;
break;
case IResource.FOLDER :
continue nextResource;
}
if (nonRubyResources.length == nonRubyResourcesCounter) {
// resize
System.arraycopy(nonRubyResources, 0, (nonRubyResources = new IResource[nonRubyResourcesCounter * 2]), 0, nonRubyResourcesCounter);
}
nonRubyResources[nonRubyResourcesCounter++] = member;
}
if (nonRubyResources.length != nonRubyResourcesCounter) {
System.arraycopy(nonRubyResources, 0, (nonRubyResources = new IResource[nonRubyResourcesCounter]), 0, nonRubyResourcesCounter);
}
return nonRubyResources;
} catch (CoreException e) {
throw new RubyModelException(e);
}
}
/**
* Starting at this folder, create non-ruby resources for this package fragment root
* and add them to the non-ruby resources collection.
*
* @exception RubyModelException The resource associated with this package fragment does not exist
*/
static Object[] computeFolderNonRubyResources(RubyProject project, IContainer folder, char[][] inclusionPatterns, char[][] exclusionPatterns) throws RubyModelException {
Object[] nonRubyResources = new IResource[5];
int nonRubyResourcesCounter = 0;
try {
ILoadpathEntry[] classpath = project.getResolvedLoadpath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
IResource[] members = new IResource[0];
if (folder != null) members = folder.members();
nextResource: for (int i = 0, max = members.length; i < max; i++) {
IResource member = members[i];
switch (member.getType()) {
case IResource.FILE :
String fileName = member.getName();
// ignore .rb, .erb, .rhtml files that are not excluded
if (Util.isValidRubyOrERBScriptName(fileName) && !Util.isExcluded(member, inclusionPatterns, exclusionPatterns))
continue nextResource;
break;
case IResource.FOLDER :
// ignore valid packages or excluded folders that correspond to a nested pkg fragment root
if (Util.isValidSourceFolderName(member.getName())
&& (!Util.isExcluded(member, inclusionPatterns, exclusionPatterns)
|| isLoadpathEntry(member.getFullPath(), classpath)))
continue nextResource;
break;
}
if (nonRubyResources.length == nonRubyResourcesCounter) {
// resize
System.arraycopy(nonRubyResources, 0, (nonRubyResources = new IResource[nonRubyResourcesCounter * 2]), 0, nonRubyResourcesCounter);
}
nonRubyResources[nonRubyResourcesCounter++] = member;
}
if (nonRubyResources.length != nonRubyResourcesCounter) {
System.arraycopy(nonRubyResources, 0, (nonRubyResources = new IResource[nonRubyResourcesCounter]), 0, nonRubyResourcesCounter);
}
return nonRubyResources;
} catch (CoreException e) {
throw new RubyModelException(e);
}
}
private static boolean isLoadpathEntry(IPath path, ILoadpathEntry[] resolvedLoadpath) {
for (int i = 0, length = resolvedLoadpath.length; i < length; i++) {
ILoadpathEntry entry = resolvedLoadpath[i];
if (entry.getPath().equals(path)) {
return true;
}
}
return false;
}
/**
* Returns an array of non-java resources contained in the receiver.
*/
synchronized Object[] getNonRubyResources(IRubyProject project, IResource underlyingResource, SourceFolderRoot handle) {
Object[] nonRubyResources = this.fNonRubyResources;
if (nonRubyResources == null) {
nonRubyResources = this.computeNonRubyResources(project, underlyingResource, handle);
this.fNonRubyResources = nonRubyResources;
}
return nonRubyResources;
}
/**
* Compute the non-ruby resources of this source folder root.
*/
private Object[] computeNonRubyResources(IRubyProject project, IResource underlyingResource, SourceFolderRoot handle) {
Object[] nonRubyResources = NO_NON_RUBY_RESOURCES;
try {
// the underlying resource may be a folder or a project (in the case that the project folder
// is actually the source folder root)
if (underlyingResource.getType() == IResource.FOLDER || underlyingResource.getType() == IResource.PROJECT) {
nonRubyResources =
computeFolderNonRubyResources(
(RubyProject)project,
(IContainer) underlyingResource,
handle.fullInclusionPatternChars(),
handle.fullExclusionPatternChars());
}
} catch (RubyModelException e) {
// ignore
}
return nonRubyResources;
}
}