Java tutorial
/******************************************************************************* * Copyright 2017 Capital One Services, LLC and Bitwise, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package hydrograph.ui.project.structure.wizard; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.codehaus.plexus.util.StringUtils; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; 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.launching.JavaRuntime; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.slf4j.Logger; import hydrograph.ui.common.util.Constants; import hydrograph.ui.logging.factory.LogFactory; import hydrograph.ui.project.structure.Activator; import hydrograph.ui.project.structure.CustomMessages; import hydrograph.ui.project.structure.natures.ProjectNature; /** * Class to create the Custom Project Structure. * */ public class ProjectStructureCreator { private static final String ORG_ECLIPSE_M2E_CORE_MAVEN2_NATURE = "org.eclipse.m2e.core.maven2Nature"; private static final String POM_XML = "pom.xml"; private static final String MAVEN = "maven"; private static final String TEMPLATE_PROJECT_NAME = "templateProjectName"; private static final String PROPERTIES = "properties"; private static final String BUILD = "build"; private static final Logger logger = LogFactory.INSTANCE.getLogger(ProjectStructureCreator.class); public static final String[] paths = { CustomMessages.ProjectSupport_Settings, CustomMessages.ProjectSupport_JOBS, CustomMessages.ProjectSupport_RESOURCES, Constants.ProjectSupport_SRC, CustomMessages.ProjectSupport_SCRIPTS, CustomMessages.ProjectSupport_PARAM, CustomMessages.ProjectSupport_GLOBAL_PARAM, CustomMessages.ProjectSupport_SCHEMA, CustomMessages.ProjectSupport_LIB }; public static final ProjectStructureCreator INSTANCE = new ProjectStructureCreator(); private ProjectStructureCreator() { } /** * Creates the custom project structure at the specified location and name * The Project will have below natures:<br> * <b>Java</b> and Custom nature as per <b>ETL</b> project * @param projectName Project name * @param location Where should the project be saved * @return */ public IProject createProject(String projectName, URI location) { if (StringUtils.isNotBlank(projectName) && projectName.contains(" ")) { MessageBox messageBox = new MessageBox(new Shell(), SWT.ICON_ERROR | SWT.OK); messageBox.setText("Error"); messageBox.setMessage("The Project Name has spaces"); if (messageBox.open() == SWT.OK) { return null; } } else if (StringUtils.isBlank(projectName)) { throw new InvalidProjectNameException(); } IProject project = null; try { project = createBaseProject(projectName, location); if (project != null) { addNature(project); addToProjectStructure(project, paths); IJavaProject javaProject = JavaCore.create(project); IFolder binFolder = project.getFolder(CustomMessages.ProjectSupport_BIN); javaProject.setOutputLocation(binFolder.getFullPath(), null); List<IClasspathEntry> entries = addJavaLibrariesInClassPath(); IFolder libFolder = project.getFolder(CustomMessages.ProjectSupport_LIB); //add libs to project class path String installLocation = Platform.getInstallLocation().getURL().getPath(); //copyExternalLibAndAddToClassPath(installLocation + CustomMessages.ProjectSupport_LIB, libFolder, entries); copyBuildFile(installLocation + CustomMessages.ProjectSupport_CONFIG_FOLDER + "/" + CustomMessages.ProjectSupport_GRADLE + "/" + BUILD, project); copyBuildFile(installLocation + CustomMessages.ProjectSupport_CONFIG_FOLDER + "/" + CustomMessages.ProjectSupport_GRADLE + "/" + PROPERTIES, project); copyBuildFile(installLocation + CustomMessages.ProjectSupport_CONFIG_FOLDER + "/" + MAVEN, project); updateMavenFile(POM_XML, project); javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), null); //set source folder entry in classpath javaProject.setRawClasspath(setSourceFolderInClassPath(project, javaProject), null); } } catch (CoreException e) { logger.debug( "Failed to create Project with parameters as projectName : {} location : {}, exception : {}", new Object[] { projectName, location, e }); project = null; } return project; } private void copyBuildFile(String source, IProject project) throws CoreException { File sourceFileLocation = new File(source); File[] listFiles = sourceFileLocation.listFiles(); if (listFiles != null) { for (File sourceFile : listFiles) { IFile destinationFile = project.getFile(sourceFile.getName()); try (InputStream fileInputStream = new FileInputStream(sourceFile)) { if (!destinationFile.exists()) { //used while importing a project destinationFile.create(fileInputStream, true, null); } } catch (IOException | CoreException exception) { logger.debug("Copy build file operation failed"); throw new CoreException(new MultiStatus(Activator.PLUGIN_ID, 100, "Copy build file operation failed", exception)); } } } } private void updateMavenFile(String source, IProject project) throws CoreException { try { IFile destinationFile = project.getFile(source); java.nio.file.Path path = Paths.get(destinationFile.getLocationURI()); Charset charset = StandardCharsets.UTF_8; String content = new String(Files.readAllBytes(path), charset); content = content.replaceAll(TEMPLATE_PROJECT_NAME, project.getName()); Files.write(path, content.getBytes(charset)); } catch (IOException exception) { logger.debug("Could not change the group and artifact name"); throw new CoreException(new MultiStatus(Activator.PLUGIN_ID, 100, "Could not change the group and artifact name", exception)); } } /** * Sets the <b>src</b> folder as the source folder in project * @param project * @param javaProject * @return IClasspathEntry[] * @throws JavaModelException */ private IClasspathEntry[] setSourceFolderInClassPath(IProject project, IJavaProject javaProject) throws JavaModelException { IFolder sourceFolder = project.getFolder(Constants.ProjectSupport_SRC); //$NON-NLS-1$ IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(sourceFolder); IClasspathEntry[] oldEntries = javaProject.getRawClasspath(); IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath()); return newEntries; } /** * Adds java libraries to the classpath * @return List < IClasspathEntry > */ private List<IClasspathEntry> addJavaLibrariesInClassPath() { List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); entries.add(JavaCore.newContainerEntry(JavaRuntime.newDefaultJREContainerPath())); entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"))); return entries; } /** * Creates the specified folder if it does not exists * @param folder * @throws CoreException */ private void createFolder(IFolder folder) throws CoreException { IContainer parent = folder.getParent(); if (parent instanceof IFolder) { createFolder((IFolder) parent); } if (!folder.exists()) { folder.create(false, true, null); } } /** * Create a folder structure as specified in the parameters * @param newProject * @param paths contains the names of the folder that need to be created. * @throws CoreException */ private void addToProjectStructure(IProject newProject, String[] paths) throws CoreException { for (String path : paths) { IFolder etcFolders = newProject.getFolder(path); createFolder(etcFolders); } } private void addNature(IProject project) throws CoreException { if (!project.hasNature(ProjectNature.NATURE_ID)) { IProjectDescription description = project.getDescription(); String[] prevNatures = description.getNatureIds(); String[] newNatures = new String[prevNatures.length + 3]; System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); newNatures[prevNatures.length] = ProjectNature.NATURE_ID; newNatures[prevNatures.length + 1] = JavaCore.NATURE_ID; newNatures[prevNatures.length + 2] = ORG_ECLIPSE_M2E_CORE_MAVEN2_NATURE; // validate the natures IWorkspace workspace = ResourcesPlugin.getWorkspace(); IStatus status = workspace.validateNatureSet(newNatures); ICommand javaBuildCommand = description.newCommand(); javaBuildCommand.setBuilderName("org.eclipse.jdt.core.javabuilder"); ICommand mavenBuildCommand = description.newCommand(); mavenBuildCommand.setBuilderName("org.eclipse.m2e.core.maven2Builder"); ICommand[] iCommand = { javaBuildCommand, mavenBuildCommand }; description.setBuildSpec(iCommand); // only apply new nature, if the status is ok if (status.getCode() == IStatus.OK) { description.setNatureIds(newNatures); project.setDescription(description, null); } logger.debug("Project nature added"); } } /** * Creates the base structure of the project under specified location and name * @param projectName * @param location * @return * @throws CoreException */ private IProject createBaseProject(String projectName, URI location) throws CoreException { IProject newProject = null; if (location == null) { newProject = createTheProjectAtSpecifiedLocation(projectName, location); } else { IPath iPath = new Path(location.getPath()); if (!StringUtils.equals(iPath.lastSegment(), projectName)) { iPath = iPath.append(projectName); } URI newLocation = URI.create(iPath.toFile().toURI().toString()); newProject = createTheProjectAtSpecifiedLocation(projectName, newLocation); } return newProject; } private IProject createTheProjectAtSpecifiedLocation(String projectName, URI location) throws CoreException { IProject newProject; newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); if (!newProject.exists()) { IProjectDescription desc = newProject.getWorkspace().newProjectDescription(newProject.getName()); if (location != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) { desc.setLocationURI(null); } else { desc.setLocationURI(location); } try { newProject.create(desc, null); if (!newProject.isOpen()) { newProject.open(null); } logger.debug("Project base structure created"); } catch (CoreException exception) { logger.debug("Project base structure creation failed"); throw exception; } } return newProject; } /* * Copy External jar to project lib directory * @param source path * @param target path * @return list of added files path */ private void copyExternalLibAndAddToClassPath(String source, IFolder destinationFolder, List<IClasspathEntry> entries) throws CoreException { File sourceFileLocation = new File(source); File[] listFiles = sourceFileLocation.listFiles(); if (listFiles != null) { for (File sourceFile : listFiles) { IFile destinationFile = destinationFolder.getFile(sourceFile.getName()); try (InputStream fileInputStream = new FileInputStream(sourceFile)) { if (!destinationFile.exists()) { //used while importing a project destinationFile.create(fileInputStream, true, null); } entries.add(JavaCore.newLibraryEntry(new Path(destinationFile.getLocation().toOSString()), null, null)); } catch (IOException | CoreException exception) { logger.debug("Copy external library files operation failed", exception); throw new CoreException(new MultiStatus(Activator.PLUGIN_ID, 101, "Copy external library files operation failed", exception)); } } } } /** * The Class InvalidProjectNameException. * * @author Bitwise */ public class InvalidProjectNameException extends RuntimeException { /** * */ private static final long serialVersionUID = -6194407190206545086L; } }