/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.core.workspace;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.jdom.Document;
import org.jdom.Element;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.common.xml.JdomHelper;
import org.teiid.designer.core.ModelerCore;
/**
* Utility class for inquiring about eclipse and Designer project-related info.
*
*
* @since 8.0
*/
public class DotProjectUtils {
public static final String DOT_PROJECT = ".project"; //$NON-NLS-1$
private DotProjectUtils() {
}
/**
* Finds and returns the a project's .project file
* @param container
* @return the .project file for this container, or null if not found
*/
public static IFile getDotProjectFile( IContainer container ) {
IProject project = container.getProject();
if (project != null) {
return container.getProject().getFile(DotProjectUtils.DOT_PROJECT);
}
return null;
}
/**
*
* Method which checks if there are multiple .project files within file.
*
* The intend was to provide a method to recognize when one project is nested within another project.
*
* @throws JDOMException
* @throws IOException
* @param File name String, boolean to recurse to second level folders, and boolean to only count modeler projects
* @return 0, 1, or 2 for 2 or greater .project files found
*/
public static int getDotProjectCount( String fileName,
boolean recurse,
boolean onlyModelerProjects ) throws Exception {
File file = new File(fileName);
return getDotProjectCount(file, recurse, onlyModelerProjects);
}
/**
* Method which checks if there are multiple .project files within file.
*
* The intend was to provide a method to recognize when one project is nested within another project.
*
* @throws JDOMException
* @throws IOException
* @param File, boolean to recurse to second level folders, and boolean to only count modeler projects
* @return 0, 1, or 2 for 2 or greater .project files found
*/
public static int getDotProjectCount( File file,
boolean recurse,
boolean onlyModelerProjects ) throws Exception {
int dotProjectCount = 0;
int depth = 0;
List<File> resources = new ArrayList<File>();
resources.add(file);
while (resources.size() > 0) {
File resource = resources.get(0);
if (resource.isFile()) {
if (isDotProject(resource, onlyModelerProjects)) {
dotProjectCount++;
}
if (dotProjectCount > 1) {
return dotProjectCount;
}
} else if (recurse || depth == 0) {
File[] members = resource.listFiles();
for (int i = 0; i < members.length; i++) {
resources.add(members[i]);
}
depth++;
}
resources.remove(0);
}
return dotProjectCount;
}
/**
* Checks file name and peeks into .project if necessary to check for modeler nature.
*
* @throws JDOMException
* @throws IOException
* @param File name and boolean to only count modeler projects
* @return
*/
public static boolean isDotProject( String file,
boolean onlyModelerProject ) throws Exception {
return isDotProject(new File(file), onlyModelerProject);
}
/**
* Checks file name and peeks into .project if necessary to check for modeler nature.
*
* @throws JDOMException
* @throws IOException
* @param File name and boolean to only count modeler projects
* @return
*/
public static boolean isDotProject( File file,
boolean onlyModelerProject ) throws Exception {
if (file == null || ! file.exists())
return false;
if (file.getName().equals(DOT_PROJECT)) {
if (onlyModelerProject) {
Document doc = JdomHelper.buildDocument(file);
Element elementFound = JdomHelper.findElement(doc.getRootElement(), "nature"); //$NON-NLS-1$
if (elementFound == null) {
return false;
}
if (elementFound.getText().equals(ModelerCore.NATURE_ID)) {
return true;
}
return false;
}
return true;
}
return false;
}
/**
* <p>
* </p>
*
* @throws JDOMException
* @throws IOException
* @throws CoreException
* @param IResource, boolean to recurse to second level folders, and boolean to only count modeler projects
* @return 0, 1, or 2 for 2 or greater .project files found
*/
public static int getDotProjectCount( IResource targetResource,
boolean recurse,
boolean onlyModelerProjects ) throws Exception {
int dotProjectCount = 0;
int depth = 0;
List<IResource> resources = new ArrayList<IResource>();
resources.add(targetResource);
while (resources.size() > 0) {
IResource resource = resources.get(0);
if (!(resource instanceof IContainer)) {
if (isDotProject(resource, onlyModelerProjects)) {
dotProjectCount++;
}
if (dotProjectCount > 1) {
return dotProjectCount;
}
} else if (recurse || depth == 0) {
IResource[] members = ((IContainer)resource).members();
for (int i = 0; i < members.length; i++) {
resources.add(members[i]);
}
depth++;
}
resources.remove(0);
}
return dotProjectCount;
}
/**
* Checks resource name and peeks into .project if necessary to check for modeler nature.
*
* @throws JDOMException
* @throws IOException
* @throws CoreException
* @param File name and boolean to only count modeler projects
* @return
*/
public static boolean isDotProject( IResource resource,
boolean onlyModelerProject ) throws Exception {
if (resource.getName().equals(DOT_PROJECT)
&& resource.getType() == IResource.FILE
&& resource.getLocation() != null) {
if (onlyModelerProject) {
if (resource.isAccessible()) {
if (resource.getProject().isOpen()) {
return resource.getProject().hasNature(ModelerCore.NATURE_ID);
}
return isModelNature(resource);
} else if (isDotProject(((IFile)resource).getLocation().toFile(), onlyModelerProject)) {
return true;
}
return false;
}
return true;
}
return false;
}
/**
* Determines if the IResource (expecting a .project) contains a Modeler Nature
*
* @param resource
* @return true if file contains the Model Nature
*/
private static boolean isModelNature( IResource resource ) {
boolean result = false;
File theFile = ((IFile)resource).getLocation().toFile();
FileReader fileReader = null;
BufferedReader bufferReader = null;
try {
fileReader = new FileReader(theFile.getPath());
bufferReader = new BufferedReader(fileReader);
String str = null;
while ((str = bufferReader.readLine()) != null && !result) {
if (str.indexOf(ModelerCore.NATURE_ID) > -1) {
result = true;
}
}
} catch (Exception e) {
ModelerCore.Util.log(IStatus.ERROR, e, e.getMessage());
} finally {
// Clean up readers & buffers
try {
if (fileReader != null) {
fileReader.close();
}
} catch (java.io.IOException e) {
ModelerCore.Util.log(IStatus.ERROR, e, e.getMessage());
}
try {
if (bufferReader != null) {
bufferReader.close();
}
} catch (java.io.IOException e) {
ModelerCore.Util.log(IStatus.ERROR, e, e.getMessage());
}
}
return result;
}
/**
* Determines if an <code>IProject</code> has a Modeler Nature
*
* This will also look at "closed" projects.
*
*
* @param iProject
* @return true if Modeler Project
*/
public static boolean isModelerProject( IProject iProject ) {
boolean result = false;
IFile dotProjectFile = DotProjectUtils.getDotProjectFile(iProject);
if (dotProjectFile != null) {
try {
result = DotProjectUtils.isDotProject(dotProjectFile, true);
} catch (Exception e) {
ModelerCore.Util.log(e);
}
}
return result;
}
/**
* Returns true if the given project is accessible and it has a java nature, otherwise false.
*
* @since 4.0
*/
public static boolean hasNature( final IProject project, final String nature ) {
CoreArgCheck.isNotNull(project);
CoreArgCheck.isNotEmpty(nature);
try {
return project.hasNature(nature);
} catch (final CoreException e) {
// project does not exist or is not open
}
return false;
}
/**
* Returns a list of open Model Projects within the workspace
*
* @return collection of Modeler <code>IProject</code>s
*/
public static Collection<IProject> getOpenModelProjects() {
IProject[] allProjects = ModelerCore.getWorkspace().getRoot().getProjects();
List<IProject> openModelProjectList = new ArrayList<IProject>(allProjects.length);
for (IProject proj : allProjects) {
if (proj.isOpen() && isModelerProject(proj) && !hasNature(proj, ModelerCore.HIDDEN_PROJECT_NATURE_ID)) {
openModelProjectList.add(proj);
}
}
return openModelProjectList;
}
public static Collection<IFile> getAllProjectResources(final IProject project) {
return WorkspaceResourceFinderUtil.getProjectFileResources(project);
}
}