Creating a Eclipse Java Project from another project, programatically - java

I would like to create a Java project from another Java project, using some script or Java methods from an Eclipse library, whether it exists. An alternative to this can be duplicating a previously manually-created project. Is there any approach to this?
Thanks.

I believe you can make use of IProject#copy (inherited from IResource.copy)

Adding to Alexander Pavlov's answer, I found that a little extra work is required to copy the project properties (such as referenced projects) in addition to just copying the project files.
public static IProject copyProject(String projectName) throws CoreException {
IProgressMonitor m = new NullProgressMonitor();
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IProject project = workspaceRoot.getProject(projectName);
IProjectDescription projectDescription = project.getDescription();
String cloneName = projectName + "_copy";
// create clone project in workspace
IProjectDescription cloneDescription = workspaceRoot.getWorkspace().newProjectDescription(cloneName);
// copy project files
project.copy(cloneDescription, true, m);
IProject clone = workspaceRoot.getProject(cloneName);
// copy the project properties
cloneDescription.setNatureIds(projectDescription.getNatureIds());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
cloneDescription.setDynamicReferences(projectDescription.getDynamicReferences());
cloneDescription.setBuildSpec(projectDescription.getBuildSpec());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
clone.setDescription(cloneDescription, null);
return clone;
}

Related

How to allow my maven plugin to access resources of a project where it is used?

I have a maven project which contain sub module :
mainproject, subproject-a, subproject-b
I'm developping a maven plugin (test-toto-plugin ) and i'd like this module check for example if toto.txt is present in src/main/resources for the project and each subproject and if it contains the line "toto".
When i include my test-toto-plugin in mainproject, it's called at each clean phase, i put a log to be sure about that, so it's called when i want, but it doesn't seem to access to src/main/resources of mainproject and each subproject, it seem that it access its own src/main/resources.
I use :
Paths.get("src","main","resources", "toto.txt");
To access the file, i'm almost sure it access test-toto-plugin /src/main/resources.
But i want to access mainproject/src/main/resources when it's called in main project, subproject-a/src/main/resources when it's called in subproject-a, subproject-b/src/main/resources when it's called in subproject-b.
Is it possible ?, any suggestion ?
Finally found a solution to my problem reading code source of maven-resources-plugin : https://github.com/apache/maven-compiler-plugin/blob/master/src/main/java/org/apache/maven/plugin/compiler/CompilerMojo.java
In my maven plugin Mojo class, i declare :
#Parameter( defaultValue = "${project.resources}", required = true, readonly = true )
private List<Resource> resources;
It will provide me the absolute path of resource of project where my plugin is used.
In the function execute of my plugin i use FileInputStream to get file content from absolute path (i just put functionnal code but ofcourse there is exception handling).
FileInputStream fis = new FileInputStream(resources.get(0).getDirectory()+"\\toto.txt");
String body = IOUtils.toString(fis, StandardCharsets.UTF_8.name());
Executed in mainproject it will access mainproject\src\main\resources\toto.txt
Executed in subproject-a it will access subproject-a\src\main\resources\toto.txt
Executed in subproject-b it will access subproject-b\src\main\resources\toto.txt
And i just have to include my plugin to mainproject to make it work in each submodule.
You can also get the folder paths using the "project.basedir" or "project.build.directory" properties.
#Parameter(defaultValue = "${project.basedir}/src/main/resources", required = true, readonly = true)
private String sourceResourceDir;
#Parameter(defaultValue = "${project.build.directory}/classes", required = true, readonly = true)
private String buildResourceDir;
public void execute() throws MojoExecutionException {
getLog().info("sourceResourceDir=" + sourceResourceDir);
getLog().info("buildResourceDir=" + buildResourceDir);
}

Netbeans file based Project, not Folder based

I'm trying to implement a new type of project based on this tutorial. The problem is that I want that my project be saved as a single file, with a custom extension, so all the content must reside on that file. Like project_name.cep (cep - custom extension project). I don't want to open a new type of file inside project, that file is my project, and I want to write nodes inside it.
This is an example of the ProjectFactory to use:
#ServiceProvider(service=ProjectFactory.class)
public class CustomProjectFactory implements ProjectFactory{
public static final String PROJECT_EXT = "cep";
//Specifies when a project is a project, i.e.,
#Override
public boolean isProject(FileObject projectDirectory) {
return PROJECT_EXT.equals(projectDirectory.getExt()); //assuming that getExt() give the file extension
}
//Specifies when the project will be opened, i.e., if the project exists:
#Override
public Project loadProject(FileObject dir, ProjectState state) throws IOException {
return isProject(dir) ? new CustomProject(dir, state) : null;
}
#Override
public void saveProject(final Project project) throws IOException, ClassCastException {
// leave unimplemented for the moment
}
}
The problem is that the FileChooser opened when I tried to open the project seems to be a DIRECTORIES_ONLY chooser, so a single file can't be opened.
Can be done? I really appreciate some example of how to do this and if is not to much to ask how to write nodes inside this single file and represent it in the explorer (just some advices).
Indeed NetBeans projects are identified on their directories.
The only way I see is to create a custom version of the NetBeans project module which allows to select files.

Programmatically accessing build.properties of a Java project through JDT API

Is there a way to access programmatically the build.properties of a Java project through the JDT API? Something like IJavaProject.getRawClasspath() just for the build.properties?
If I have an IProject/IJavaProject, can I add a line with the JDT API like this (through JDT API calls):
Before:
source.. = src/
output.. = bin/
After:
source.. = src/,\
xtend-gen/
output.. = bin/
This is a PDE object rather than JDT so you need to use the PDE APIs. There is very little documentation on the PDE APIs.
The build.properties is described by the org.eclipse.pde.core.build.IBuildModel interface. You get this using:
IProject project = ... project ...
IPluginModelBase base = PluginRegistry.findModel(project);
IBuildModel buildModel = PluginRegistry.createBuildModel(base);
You can get the entry for 'bin.includes' using
IBuildEntry entry = buildModel.getBuild().getEntry(IBuildEntry.BIN_INCLUDES);
The addToken method of IBuildEntry seems to be the way to add to the entry.
To save you need to check the model is an instance of IEditableModel and call the IEditableModel.save method.
if (buildModel instanceof IEditableModel) {
((IEditableModel)buildModel).save();
}

Setup Eclipse Workspace in Java Code

I am writing a JUnit Plug-In Test, which will open a Java Project from the WorkSpace and pass it to a third party library for further processing. This is what I have so far:
#Test
public void testJavaProjectForwarding() {
try {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IWorkspace workspace = root.getWorkspace();
Map<String, IJavaProject> javaProjects = new HashMap<>();
System.out.println("Nr. of projects: " + javaProjects.size());
for(IProject project : workspace.getProjects()) {
if(project.isOpen() && isJavaProject(project)) {
IJavaProject javaProject = JavaCore.create(project);
javaProjects.put(project.getName(), javaProject);
}
}
System.out.println("Nr. of Java projects: " + javaProjects.size());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I print out first the number of overall projects and second the number of Java projects. Both outputs are, however, 0. This is due to the empty workspace when running a Plug-in Test. My question is: how can I setup the Plug-in Test workspace to include projects? Do I have to do it in the Launch Configuration or can I add them programmatically in the test somewhere? Thanks for your help!
Create a project handle with
org.eclipse.core.resources.IWorkspaceRoot.getProject(String) (returns
IProject)
Load prepared project description:
org.eclipse.core.resources.IWorkspace.loadProjectDescription(IPath)
(returns IProjectDescription, takes a path to .project file as argument)
Actually create a project reference in workspace:
org.eclipse.core.resources.IProject.create(IProjectDescription,
IProgressMonitor)
Open the project: org.eclipse.core.resources.IProject.open(int,
IProgressMonitor)
Example: org.eclipse.ui.internal.wizards.datatransfer.WizardProjectsImportPage.createExistingProject(ProjectRecord, IProgressMonitor). It shows how to copy source project, so that unit tests don't change it. Instead of using precreated (with Eclipse, for example) project description you can create one from scratch.

Eclipse RunTime NoClassDefFoundError

I am having trouble trying to use an imported class from a jar file which is located in the referenced libraries of my project.
So I have a project which has the pydev.jar file in the Referenced Libraries. Pydev.jar contains org.python.pydev.navigator.elements.PythonNode, and I have imported this in one of the Java files. Eclipse does not give an errors when I import and use this in the Java file but when I run the project as an Eclipse application there is a java.lang.NoClassDefFoundError: org/python/pydev/navigator/elements/PythonNode exception being thrown.
Code is trying to cast an ISelection to a PythonNode as below:
IStructuredSelection sel = (IStructuredSelection)
window.getSelectionService().getSelection();
ArrayList<String> testNames = new ArrayList<String>();
Iterator<?> itr = sel.iterator();
String testName = "";
String testSuite = "";
while(itr.hasNext()) {
PythonNode selectionElement = (PythonNode) itr.next();
testName = selectionElement.toString();
testSuite = selectionElement.pythonFile.toString();
testNames.add(testSuite + "." + testName);
}
If anyone can explain why the Exception is being thrown for the use of the PythonNode class at runtime I would be very appreciative. As far as I can see it is imported correctly as it is visible in the Referenced Libraries.
I think you're building either Eclipse RCP or Eclipse plugin. Am I right?
If yes, you should put pydev.jar under plugin dependencies. Go to plugin.xml, Runtime and put pydev.jar in the classpath

Categories