Java tutorial
/************************************************************************************* * Copyright (c) 2012-2015 Red Hat, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Fred Bricon (Red Hat, Inc.) - initial API and implementation ************************************************************************************/ package org.eclipse.m2e.wtp.jpa.internal.configurators; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.apache.maven.project.MavenProject; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; 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.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jpt.common.core.resource.xml.JptXmlResource; import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.JpaWorkspace; import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetDataModelProperties; import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetInstallDataModelProperties; import org.eclipse.jpt.jpa.core.internal.facet.JpaFacetInstallDataModelProvider; import org.eclipse.jpt.jpa.core.internal.resource.persistence.PersistenceXmlResourceProvider; import org.eclipse.jpt.jpa.core.platform.JpaPlatformManager; import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistenceUnit; import org.eclipse.jst.common.project.facet.core.JavaFacet; import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil; import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider; import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate; import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework; import org.eclipse.m2e.core.project.IMavenProjectFacade; import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator; import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration; import org.eclipse.m2e.core.project.configurator.MojoExecutionKey; import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; import org.eclipse.m2e.wtp.MavenWtpPlugin; import org.eclipse.m2e.wtp.ProjectUtils; import org.eclipse.m2e.wtp.ResourceCleaner; import org.eclipse.m2e.wtp.WTPProjectsUtil; import org.eclipse.m2e.wtp.facets.FacetDetectorManager; import org.eclipse.m2e.wtp.jpa.PlatformIdentifierManager; import org.eclipse.m2e.wtp.jpa.internal.MavenJpaActivator; import org.eclipse.m2e.wtp.jpa.internal.util.JptUtils; import org.eclipse.wst.common.componentcore.ModuleCoreNature; import org.eclipse.wst.common.componentcore.datamodel.properties.IFacetDataModelProperties; import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants; import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; import org.eclipse.wst.common.project.facet.core.IFacetedProject; import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action; import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager; /** * JPA Project configurator. Will install the JPA facet on a maven project containing a persistence.xml. * * @author Fred Bricon */ @SuppressWarnings("restriction") public class JpaProjectConfigurator extends AbstractProjectConfigurator { private static final String JPA_NO_OP_LIBRARY_PROVIDER = "jpa-no-op-library-provider"; //$NON-NLS-1$ private static final String M2E_JPA_ACTIVATION_PROPERTY = "m2e.jpa.activation"; //$NON-NLS-1$ static final String PERSISTENCE_XML_KEY = "persistencexml"; //$NON-NLS-1$ @Override public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { if (!canConfigure(request.getMavenProjectFacade(), monitor)) { return; } IProject project = request.getProject(); MavenProject mavenProject = request.getMavenProject(); IFile persistenceXml = getPersistenceXml(request.getMavenProjectFacade()); if (persistenceXml == null || !persistenceXml.exists()) { //No persistence.xml => not a JPA project return; } IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor); if (facetedProject != null) { //Refresh parent in multi-module setups, or Dali throws an exception ProjectUtils.refreshHierarchy(mavenProject.getBasedir(), IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1)); //Configurators should *never* create files in the user's source folders ResourceCleaner cleaner = new ResourceCleaner(facetedProject.getProject()); addFoldersToClean(cleaner, request.getMavenProjectFacade()); try { configureFacets(facetedProject, request.getMavenProjectFacade(), persistenceXml, monitor); } finally { cleaner.cleanUp(); } } } private IFile getPersistenceXml(IMavenProjectFacade mavenProjectFacade) { MavenResourceLocator resourceLocator = new MavenResourceLocator(); IPath path = resourceLocator.lookupMavenResources(mavenProjectFacade, new Path("META-INF/persistence.xml")); //$NON-NLS-1$ IFile persistenceXml = null; if (path != null) { persistenceXml = ResourcesPlugin.getWorkspace().getRoot().getFile(path); } return persistenceXml; } private void configureFacets(IFacetedProject facetedProject, IMavenProjectFacade mavenProjectFacade, IFile persistenceXml, IProgressMonitor monitor) throws CoreException { //Need to refresh the persistence.xml as the resource provider might crash badly on some occasions //if it finds the file is out-of-sync persistenceXml.refreshLocal(IResource.DEPTH_ZERO, null); PersistenceXmlResourceProvider provider = PersistenceXmlResourceProvider .getXmlResourceProvider(persistenceXml); JptXmlResource jpaXmlResource = provider.getXmlResource(); Map<?, ?> context = Collections.singletonMap(PERSISTENCE_XML_KEY, jpaXmlResource); FacetDetectorManager facetDetectorManager = FacetDetectorManager.getInstance(); IProjectFacetVersion version = facetDetectorManager.findFacetVersion(mavenProjectFacade, JpaProject.FACET.getId(), context, monitor); if (version == null) { return; } JpaPlatform.Config platform = getPlatform(jpaXmlResource, version); IDataModel dataModel = getDataModel(facetedProject, version, platform); Set<Action> actions = new LinkedHashSet<>(); installJavaFacet(actions, facetedProject.getProject(), facetedProject); actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, version, dataModel)); facetedProject.modify(actions, monitor); } private JpaPlatform.Config getPlatform(JptXmlResource persistenceXml, IProjectFacetVersion facetVersion) { XmlPersistenceUnit xmlPersistenceUnit = JptUtils.getFirstXmlPersistenceUnit(persistenceXml); if (xmlPersistenceUnit == null) { return null; } PlatformIdentifierManager identifierManager = MavenJpaActivator.getDefault().getPlatformIdentifierManager(); String platformType = identifierManager.identify(xmlPersistenceUnit); JpaPlatformManager platformManager = getPlatformManager(); if (platformType != null) { for (JpaPlatform.Config platform : platformManager.getJpaPlatformConfigs(facetVersion)) { if (platform.getId().contains(platformType)) { return platform; } } } //If no adequate platform found, Dali will use a default one. return null; } private JpaPlatformManager getPlatformManager() { IWorkspace workspace = ResourcesPlugin.getWorkspace(); JpaWorkspace jpaWorkspace = (JpaWorkspace) workspace.getAdapter(JpaWorkspace.class); return jpaWorkspace.getJpaPlatformManager(); } private IDataModel getDataModel(IFacetedProject facetedProject, IProjectFacetVersion version, JpaPlatform.Config platformConfig) { IDataModel dm = DataModelFactory.createDataModel(new JpaFacetInstallDataModelProvider()); dm.setProperty(IFacetDataModelProperties.FACET_VERSION_STR, version.getVersionString()); dm.setProperty(JpaFacetDataModelProperties.PLATFORM, platformConfig); //Gone in Kepler M7 dm.setProperty(JpaFacetInstallDataModelProperties.CREATE_ORM_XML, false); dm.setProperty(JpaFacetInstallDataModelProperties.DISCOVER_ANNOTATED_CLASSES, true); LibraryInstallDelegate libraryInstallDelegate = getNoOpLibraryProvider(facetedProject, version); dm.setProperty(JpaFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE, libraryInstallDelegate); return dm; } private boolean canConfigure(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException { if (!WTPProjectsUtil.isLastConfigurator(facade, getClass(), getId())) { return false; } boolean enabled = isConfigurationEnabled(facade, monitor); if (!enabled) { return false; } IProject project = facade.getProject(); // Bug 430178 : If imported project has modulecore nature without the component file, // Dali's ModuleResourceLocator#getRootFolder will NPE (ex: it.cosenonjaviste:jsf2-spring4-jpa2-archetype:1.0.3) if (!project.hasNature(JavaCore.NATURE_ID) || (project.hasNature(IModuleConstants.MODULE_NATURE_ID) && !ModuleCoreNature.componentResourceExists(project))) { return false; } IFacetedProject fProj = ProjectFacetsManager.create(project); return fProj == null || !fProj.hasProjectFacet(JpaProject.FACET); } private boolean isConfigurationEnabled(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException { if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)) { return false; } Object pomActivationValue = facade.getMavenProject(monitor).getProperties() .get(M2E_JPA_ACTIVATION_PROPERTY); boolean enabled; if (pomActivationValue == null) { enabled = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().isEnabled(getId()); } else { enabled = Boolean.parseBoolean(pomActivationValue.toString()); } return enabled; } private LibraryInstallDelegate getNoOpLibraryProvider(IFacetedProject facetedProject, IProjectFacetVersion facetVersion) { LibraryInstallDelegate libraryDelegate = new LibraryInstallDelegate(facetedProject, facetVersion); ILibraryProvider provider = LibraryProviderFramework.getProvider(JPA_NO_OP_LIBRARY_PROVIDER); libraryDelegate.setLibraryProvider(provider); return libraryDelegate; } @Override public boolean hasConfigurationChanged(IMavenProjectFacade newFacade, ILifecycleMappingConfiguration oldProjectConfiguration, MojoExecutionKey key, IProgressMonitor monitor) { //Changes to maven-compiler-plugin in pom.xml don't make it "dirty" wrt JPA config return false; } private void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject) { IProjectFacetVersion javaFv = JavaFacet.FACET.getVersion(JavaFacetUtil.getCompilerLevel(project)); if (!facetedProject.hasProjectFacet(JavaFacet.FACET)) { actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, javaFv, null)); } else if (!facetedProject.hasProjectFacet(javaFv)) { actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, javaFv, null)); } } protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) { for (IPath p : facade.getCompileSourceLocations()) { if (p != null) { fileCleaner.addFiles(p.append("META-INF/persistence.xml")); //$NON-NLS-1$ fileCleaner.addFiles(p.append("META-INF/orm.xml")); //$NON-NLS-1$ fileCleaner.addFolder(p); } } for (IPath p : facade.getResourceLocations()) { if (p != null) { fileCleaner.addFiles(p.append("META-INF/persistence.xml")); //$NON-NLS-1$ fileCleaner.addFiles(p.append("META-INF/orm.xml")); //$NON-NLS-1$ fileCleaner.addFolder(p); } } for (IPath p : facade.getTestCompileSourceLocations()) { if (p != null) { fileCleaner.addFolder(p); } } for (IPath p : facade.getTestResourceLocations()) { if (p != null) { fileCleaner.addFolder(p); } } } }