/* license-start * * Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 3. * * This program 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 General Public License for more details, at <http://www.gnu.org/licenses/>. * * Contributors: * Crispico - Initial API and implementation * * license-end */ package org.flowerplatform.editor.java.propertypage.remote; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; 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.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.launching.JavaRuntime; import org.flowerplatform.common.CommonPlugin; import org.flowerplatform.common.util.Pair; import org.flowerplatform.communication.CommunicationPlugin; import org.flowerplatform.communication.service.ServiceInvocationContext; import org.flowerplatform.communication.stateful_service.RemoteInvocation; import org.flowerplatform.communication.tree.remote.GenericTreeStatefulService; import org.flowerplatform.communication.tree.remote.PathFragment; import org.flowerplatform.web.projects.remote.ProjectsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Cristina Constantinescu */ public class JavaProjectPropertyPageService { private static final String SERVICE_ID = "javaProjectPropertyPageService"; private static final Logger logger = LoggerFactory.getLogger(JavaProjectPropertyPageService.class); public static JavaProjectPropertyPageService getInstance() { return (JavaProjectPropertyPageService) CommunicationPlugin.getInstance().getServiceRegistry().getService(SERVICE_ID); } private boolean isJavaProject(IProject project) { try { return project.hasNature(JavaCore.NATURE_ID); } catch (CoreException e) { logger.error("Exception thrown while getting java nature for {}", project.getName(), e); } return false; } @RemoteInvocation public boolean hasJavaNature(ServiceInvocationContext context, List<PathFragment> path) { @SuppressWarnings("unchecked") Pair<File, String> node = (Pair<File, String>) GenericTreeStatefulService.getNodeByPathFor(path, null); File projectFile = node.a; IProject project = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).b; return isJavaProject(project); } public boolean setJavaNature(ServiceInvocationContext context, List<PathFragment> path) { @SuppressWarnings("unchecked") Pair<File, String> node = (Pair<File, String>) GenericTreeStatefulService.getNodeByPathFor(path, null); File projectFile = node.a; final IProject project = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).b; ISchedulingRule rule = project.getWorkspace().getRuleFactory().modifyRule(project); // scheduling rule for modifying the project IWorkspaceRunnable runnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { IProjectDescription description = project.getDescription(); String[] prevNatures = description.getNatureIds(); String[] newNatures; if (isJavaProject(project)) { // remove java nature newNatures = new String[prevNatures.length - 1]; int i = 0; for (String nature : prevNatures) { if (!JavaCore.NATURE_ID.equals(nature)) { newNatures[i++] = nature; } } } else { // add java nature newNatures = new String[prevNatures.length + 1]; System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); newNatures[prevNatures.length] = JavaCore.NATURE_ID; } description.setNatureIds(newNatures); project.setDescription(description, IResource.AVOID_NATURE_CONFIG, null); } }; try { project.getWorkspace().run(runnable, rule, IWorkspace.AVOID_UPDATE, null); } catch (CoreException e) { logger.error("Exception thrown while setting java nature for {}", project.getName(), e); return false; } return true; } public Object getClasspathEntries(ServiceInvocationContext context, List<PathFragment> path) { @SuppressWarnings("unchecked") Pair<File, String> node = (Pair<File, String>) GenericTreeStatefulService.getNodeByPathFor(path, null); File projectFile = node.a; File wd = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).a; IProject project = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).b; IJavaProject javaProject = JavaCore.create(project); List<String> srcFolders = new ArrayList<String>(); List<String> projects = new ArrayList<String>(); List<String> libraries = new ArrayList<String>(); try { if (!project.getFile(IJavaProject.CLASSPATH_FILE_NAME).exists()) { return null; } @SuppressWarnings("restriction") IClasspathEntry[][] entries = ((JavaProject) javaProject).readFileEntriesWithException(null); for (IClasspathEntry entry : entries[0]) { if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { srcFolders.add(entry.getPath().makeRelativeTo(project.getFolder(ProjectsService.LINK_TO_PROJECT).getFullPath()).toFile().getPath()); } else if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { File file = ProjectsService.getInstance().getFileFromProjectWrapperResource(ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().lastSegment())); projects.add(CommonPlugin.getInstance().getPathRelativeToFile(file, wd)); } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getContentKind() == IPackageFragmentRoot.K_BINARY) { IFile resource = ResourcesPlugin.getWorkspace().getRoot().getFile(entry.getPath()); File file = ProjectsService.getInstance().getFileFromProjectWrapperResource(resource); libraries.add(CommonPlugin.getInstance().getPathRelativeToFile(file, wd)); } } } catch (CoreException | IOException e) { logger.error("Exception thrown while getting java classpath entries for {}", project.getName(), e); return null; } return new Object[] {srcFolders, projects, libraries}; } /** * @author Cristina Constantinescu * @author Mariana Gheorghe - added linked source folders and JRE container */ public boolean setClasspathEntries(ServiceInvocationContext context, List<PathFragment> path, List<String> srcFolders, List<String> projects, List<String> libraries) { @SuppressWarnings("unchecked") Pair<File, String> node = (Pair<File, String>) GenericTreeStatefulService.getNodeByPathFor(path, null); File projectFile = node.a; IProject project = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).b; IJavaProject javaProject = JavaCore.create(project); File wd = ProjectsService.getInstance().getProjectToWorkingDirectoryAndIProjectMap().get(projectFile).a; List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); for (String srcFolder : srcFolders) { entries.add(JavaCore.newSourceEntry(project.getFolder(ProjectsService.LINK_TO_PROJECT).getFullPath().append(srcFolder))); } for (String projectName : projects) { entries.add(JavaCore.newProjectEntry(ProjectsService.getInstance().getProjectWrapperResourceFromFile(new File(wd, projectName)).getFullPath())); } for (String library : libraries) { entries.add(JavaCore.newLibraryEntry(ProjectsService.getInstance().getProjectWrapperResourceFromFile(new File(wd, library)).getFullPath(), null, null)); } // default entry entries.add(JavaRuntime.getDefaultJREContainerEntry()); try { javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), new NullProgressMonitor()); } catch (JavaModelException e) { logger.error("Exception thrown while setting java classpath entries for {}", project.getName(), e); return false; } return true; } }