/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.eclipse.console.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.eclipse.core.internal.resources.File;
import org.eclipse.core.internal.resources.ICoreConstants;
import org.eclipse.core.internal.resources.ResourceInfo;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.hibernate.console.ConsoleConfiguration;
import org.hibernate.console.preferences.ConsoleConfigurationPreferences;
import org.hibernate.eclipse.console.HibernateConsoleMessages;
import org.hibernate.eclipse.console.HibernateConsolePlugin;
import org.hibernate.eclipse.console.properties.HibernatePropertiesConstants;
import org.hibernate.eclipse.launch.IConsoleConfigurationLaunchConstants;
import org.hibernate.util.xpl.StringHelper;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.xml.sax.InputSource;
@SuppressWarnings("restriction")
public class ProjectUtils {
private ProjectUtils() {
}
public static boolean toggleHibernateOnProject(IProject project, boolean enable,String defaultConsoleName) {
IScopeContext scope = new ProjectScope(project);
Preferences node = scope.getNode(HibernatePropertiesConstants.HIBERNATE_CONSOLE_NODE);
if(node!=null) {
node.putBoolean(HibernatePropertiesConstants.HIBERNATE3_ENABLED, enable );
node.put(HibernatePropertiesConstants.DEFAULT_CONFIGURATION, defaultConsoleName );
try {
node.flush();
} catch (BackingStoreException e) {
HibernateConsolePlugin.getDefault().logErrorMessage(HibernateConsoleMessages.ProjectUtils_could_not_save_changes_to_preferences, e);
return false;
}
} else {
return false;
}
try {
if(enable) {
return ProjectUtils.addProjectNature(project, HibernatePropertiesConstants.HIBERNATE_NATURE, new NullProgressMonitor() );
} else {
return ProjectUtils.removeProjectNature(project, HibernatePropertiesConstants.HIBERNATE_NATURE, new NullProgressMonitor() );
}
} catch(CoreException ce) {
HibernateConsolePlugin.getDefault().logErrorMessage(HibernateConsoleMessages.ProjectUtils_could_not_activate_hibernate_nature_on_project + project.getName(), ce);
HibernateConsolePlugin.getDefault().log(ce.getStatus() );
return false;
}
}
/**
* Add the given project nature to the given project (if it isn't already added).
* @return true if nature where added, false if not
* @throws OperationCanceledException if job were cancelled or CoreException if something went wrong.
*/
public static boolean addProjectNature(IProject project, String nature, IProgressMonitor monitor) throws CoreException {
if (monitor != null && monitor.isCanceled() ) {
throw new OperationCanceledException();
}
if (!project.hasNature(nature) ) {
IProjectDescription description = project.getDescription();
String[] prevNatures= description.getNatureIds();
String[] newNatures= new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length]= nature;
description.setNatureIds(newNatures);
project.setDescription(description, monitor);
return true;
} else {
monitor.worked(1);
return false;
}
}
public static boolean removeProjectNature(IProject project, String nature, NullProgressMonitor monitor) throws CoreException {
if (monitor != null && monitor.isCanceled() ) {
throw new OperationCanceledException();
}
if (project.hasNature(nature) ) {
IProjectDescription description = project.getDescription();
String[] natures = description.getNatureIds();
String[] newNatures = new String[natures.length - 1];
for(int i = 0, j = 0; i < natures.length; i++) {
if (!natures[i].equals(nature)) {
newNatures[j++] = natures[i];
}
}
description.setNatureIds(newNatures);
project.setDescription(description, monitor);
return true;
} else {
monitor.worked(1);
return false;
}
}
static public IJavaProject findJavaProject(IEditorPart part) {
if(part!=null) return findJavaProject(part.getEditorInput());
return null;
}
static public IJavaProject findJavaProject(IEditorInput input) {
if(input!=null && input instanceof IFileEditorInput) {
IFile file = null;
IProject project = null;
IJavaProject jProject = null;
IFileEditorInput fileInput = (IFileEditorInput) input;
file = fileInput.getFile();
project = file.getProject();
jProject = JavaCore.create(project);
return jProject;
}
return null;
}
/**
* Returns a handle to the project resource with the given name
* which is a child of workspace.
* @param name - java project name
* @return a handle to the project resource
*/
public static IProject findProject(String name) {
if (StringHelper.isEmpty(name)) {
return null;
}
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(name);
return project;
}
/**
* Returns the created Java project corresponding to the given name.
* @param name - java project name
* @return a Java project
*/
public static IJavaProject findJavaProject(String name) {
IProject project = findProject(name);
if (project != null) {
return JavaCore.create(project);
}
return null;
}
/**
* Returns a handle to the project resource corresponding to
* the given console configuration name.
* @param consoleConfiguration
* @return a handle to the project resource
*/
public static IProject findProject(ConsoleConfiguration consoleConfiguration) {
if (consoleConfiguration != null) {
try {
ILaunchConfiguration launchConfiguration = LaunchHelper.findHibernateLaunchConfig(
consoleConfiguration.getName());
if(launchConfiguration != null) {
String projName = launchConfiguration.getAttribute(
IConsoleConfigurationLaunchConstants.PROJECT_NAME, ""); //$NON-NLS-1$
return findProject(projName);
}
} catch (CoreException e1) {
HibernateConsolePlugin.getDefault().log(e1);
}
}
return null;
}
/**
* Returns the created Java project corresponding to
* the given console configuration name.
* @param consoleConfiguration
* @return a Java project
*/
public static IJavaProject findJavaProject(ConsoleConfiguration consoleConfiguration) {
IProject project = findProject(consoleConfiguration);
if (project != null) {
return JavaCore.create(project);
}
return null;
}
/**
* Checks is file, folder or project exist.
* @param file
* @return true if a resource exist
*/
public static boolean exists(IFile f) {
if (!(f instanceof File)) {
return false;
}
File file = (File)f;
ResourceInfo info = file.getResourceInfo(false, false);
int flags = file.getFlags(info);
if (flags != ICoreConstants.NULL_FLAG) {
int type = ResourceInfo.getType(flags);
if (type == IResource.FILE || type == IResource.FOLDER || type == IResource.PROJECT) {
return true;
}
}
return false;
}
private static boolean updateCollection(ArrayList<IProject> projects, IProject project) {
if (project == null) {
return false;
}
for (Iterator<IProject> it = projects.iterator(); it.hasNext();) {
if (project.equals(it.next())) {
return false;
}
}
projects.add(project);
return true;
}
/**
* Returns the created Java projects corresponding to
* the given console configuration (classpath & console configuration name).
* Projects are listed in priority order, sequence is important.
*
* @param consoleConfiguration
* @return a list of Java projects in order
*/
public static IJavaProject[] findJavaProjects(ConsoleConfiguration consoleConfiguration) {
ConsoleConfigurationPreferences ccp = consoleConfiguration.getPreferences();
URL[] classPathURLs = new URL[0];
if (ccp != null) {
classPathURLs = ccp.getCustomClassPathURLS();
}
ArrayList<IProject> projects = new ArrayList<IProject>();
IFile file = null;
for (int i = 0; i < classPathURLs.length; i++) {
IPath path = Path.fromOSString(classPathURLs[i].getFile());
file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if (file == null || !exists(file)) {
file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
}
if (file != null && exists(file)) {
updateCollection(projects, file.getProject());
}
}
// insert this in last place
updateCollection(projects, findProject(consoleConfiguration));
List<IJavaProject> res = new ArrayList<IJavaProject>();
for (int i = 0; i < projects.size(); i++) {
try {
if (projects.get(i).isOpen() && projects.get(i).hasNature(JavaCore.NATURE_ID)){
res.add(JavaCore.create(projects.get(i)));
}
} catch (CoreException e) {
HibernateConsolePlugin.getDefault().log(e);
}
}
return res.toArray(new IJavaProject[0]);
}
static public org.eclipse.jdt.core.dom.CompilationUnit getCompilationUnit(
ICompilationUnit source, boolean bindings) {
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setSource(source);
parser.setResolveBindings(bindings);
org.eclipse.jdt.core.dom.CompilationUnit result = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
return result;
}
static public ICompilationUnit findCompilationUnit(IJavaProject javaProject,
String fullyQualifiedName) {
IType lwType = findType(javaProject, fullyQualifiedName);
if (lwType != null) {
return lwType.getCompilationUnit();
}
return null;
}
static public IType findType(IJavaProject javaProject,
String fullyQualifiedName) {
IType lwType = null;
try {
lwType = javaProject.findType(fullyQualifiedName);
} catch (JavaModelException e) {
// just ignore it!
}
return lwType;
}
static public String getParentTypename(IJavaProject proj, String fullyQualifiedName) {
String res = null;
ICompilationUnit icu = findCompilationUnit(proj, fullyQualifiedName);
if (icu == null) {
return res;
}
org.eclipse.jdt.core.dom.CompilationUnit cu = getCompilationUnit(icu, true);
if (cu == null) {
return res;
}
List<?> types = cu.types();
for (int i = 0; i < types.size() && res == null; i++) {
Object obj = types.get(i);
if (!(obj instanceof TypeDeclaration)) {
continue;
}
TypeDeclaration td = (TypeDeclaration)obj;
Type superType = td.getSuperclassType();
if (superType != null) {
ITypeBinding tb = superType.resolveBinding();
if (tb != null) {
if (tb.getJavaElement() instanceof SourceType) {
SourceType sourceT = (SourceType)tb.getJavaElement();
try {
res = sourceT.getFullyQualifiedParameterizedName();
}
catch (JavaModelException e) {
HibernateConsolePlugin.getDefault().logErrorMessage("JavaModelException: ", e); //$NON-NLS-1$
}
}
}
}
}
return res;
}
/**
* Collects all persistent unit names: available in the project and required projects
* @param javaProject
* @return
*/
public static String[] availablePersistenceUnits(IJavaProject javaProject) {
if (javaProject != null && javaProject.isOpen()){
Set<IJavaProject> projects = new HashSet<IJavaProject>();
projects.add(javaProject);
try {
String[] requiredProjectNames = javaProject.getRequiredProjectNames();
for (String projectName : requiredProjectNames) {
IProject project = findProject(projectName);
try {
if (project != null && project.isAccessible() && project.hasNature(JavaCore.NATURE_ID)){
projects.add(JavaCore.create(project));
}
} catch (CoreException e) {
HibernateConsolePlugin.getDefault().log(e);
}
}
} catch (JavaModelException e) {
HibernateConsolePlugin.getDefault().log(e);
}
Set<String> puNames = new TreeSet<String>();
for (IJavaProject iJavaProject : projects) {
for (String puName : projectPersistenceUnits(iJavaProject)) {
puNames.add(puName);
}
}
return puNames.toArray(new String[puNames.size()]);
}
return new String[0];
}
private static String[] projectPersistenceUnits(IJavaProject javaProject) {
if (javaProject == null || javaProject.getResource() == null) {
return new String[0];
}
IPath projPathFull = javaProject.getResource().getLocation();
IPath projPath = javaProject.getPath();
IPath path = javaProject.readOutputLocation().append("META-INF/persistence.xml"); //$NON-NLS-1$
path = path.makeRelativeTo(projPath);
path = projPathFull.append(path);
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
if (!exists(file)) {
return new String[0];
}
InputStream is = null;
org.dom4j.Document doc = null;
try {
is = file.getContents();
SAXReader saxReader = new SAXReader();
doc = saxReader.read(new InputSource(is));
} catch (CoreException e) {
HibernateConsolePlugin.getDefault().logErrorMessage("CoreException: ", e); //$NON-NLS-1$
} catch (DocumentException e) {
HibernateConsolePlugin.getDefault().logErrorMessage("DocumentException: ", e); //$NON-NLS-1$
} finally {
try {
if (is != null) is.close();
}
catch (IOException ioe) {
//ignore
}
}
if (doc == null || doc.getRootElement() == null) {
return new String[0];
}
Iterator<?> it = doc.getRootElement().elements("persistence-unit").iterator(); //$NON-NLS-1$
ArrayList<String> res = new ArrayList<String>();
while (it.hasNext()) {
Element el = (Element)it.next();
res.add(el.attributeValue("name")); //$NON-NLS-1$
}
return res.toArray(new String[0]);
}
}