/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library 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 library 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. * *******************************************************************************/ package com.liferay.ide.gradle.core; import aQute.bnd.osgi.Jar; import com.liferay.blade.gradle.model.CustomModel; import com.liferay.ide.core.BaseLiferayProject; import com.liferay.ide.core.IBundleProject; import com.liferay.ide.core.IResourceBundleProject; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.core.util.FileUtil; import com.liferay.ide.core.util.PropertiesUtil; import com.liferay.ide.project.core.IProjectBuilder; import com.liferay.ide.project.core.util.ProjectUtil; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; 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.Path; import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.gradle.tooling.BuildLauncher; import org.gradle.tooling.GradleConnectionException; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ProjectConnection; /** * @author Gregory Amerson * @author Terry Jia * @author Andy Wu */ public class LiferayGradleProject extends BaseLiferayProject implements IBundleProject, IResourceBundleProject { private static final String[] ignorePaths = new String[] { ".gradle", "build", "dist", "liferay-theme.json" }; public <T> T adapt( Class<T> adapterType ) { T adapter = super.adapt( adapterType ); if( adapter != null ) { return adapter; } if( IProjectBuilder.class.equals( adapterType ) ) { final IProjectBuilder projectBuilder = new GradleProjectBuilder( getProject() ); return adapterType.cast( projectBuilder ); } return null; } public static IPath getOutputBundlePath( IProject gradleProject ) { IPath retval = null; final CustomModel model = GradleCore.getToolingModel( GradleCore.getDefault(), CustomModel.class, gradleProject ); Set<File> outputFiles = model.getOutputFiles(); if( outputFiles.size() > 0 ) { // first check to see if there are any outputfiles that are wars, if so use that one. File bundleFile = null; for( File outputFile : outputFiles ) { if( outputFile.getName().endsWith( ".war" ) ) { bundleFile = outputFile; break; } } if( bundleFile == null ) { for( File outputFile : outputFiles ) { if( outputFile.getName().endsWith( ".jar" ) ) { bundleFile = outputFile; break; } } } if( bundleFile != null ) { retval = new Path( bundleFile.getAbsolutePath() ); } } else if( model.hasPlugin( "com.liferay.gradle.plugins.gulp.GulpPlugin" ) ) { retval = gradleProject.getLocation().append( "dist/" + gradleProject.getName() + ".war" ); } return retval; } public LiferayGradleProject( IProject project ) { super( project ); } @Override public boolean filterResource( IPath resourcePath ) { if( filterResource( resourcePath, ignorePaths ) ) { return true; } return false; } @Override public String getBundleShape() { return "jar"; } @Override public List<IFile> getDefaultLanguageProperties() { return PropertiesUtil.getDefaultLanguagePropertiesFromModuleProject( getProject() ); } @Override public IFolder getSourceFolder( String classification ) { IFolder retval = null; IFolder[] sourceFolders = getSourceFolders(); for( IFolder folder : sourceFolders ) { if( folder.getName().equals( classification ) ) { retval = folder; break; } } if( classification.equals( "resources" ) ) { if( retval == null ) { retval = createResorcesFolder( getProject() ); } } return retval; } @Override public IFolder[] getSourceFolders() { final IFile gulpFile = getProject().getFile( "gulpfile.js" ); if( gulpFile != null && gulpFile.exists() ) { return new IFolder[] { getProject().getFolder( "src" ) }; } return super.getSourceFolders(); } private IFolder createResorcesFolder( IProject project ) { try { IJavaProject javaProject = JavaCore.create( project ); List<IClasspathEntry> existingRawClasspath; existingRawClasspath = Arrays.asList( javaProject.getRawClasspath() ); List<IClasspathEntry> newRawClasspath = new ArrayList<IClasspathEntry>(); IClasspathAttribute[] attributes = new IClasspathAttribute[] { JavaCore.newClasspathAttribute( "FROM_GRADLE_MODEL", "true" ) }; //$NON-NLS-1$ //$NON-NLS-2$ IClasspathEntry resourcesEntry = JavaCore.newSourceEntry( project.getFullPath().append( "src/main/resources" ), new IPath[0], new IPath[0], null, attributes ); for( IClasspathEntry entry : existingRawClasspath ) { newRawClasspath.add( entry ); } if( !existingRawClasspath.contains( resourcesEntry ) ) { newRawClasspath.add( resourcesEntry ); } javaProject.setRawClasspath( newRawClasspath.toArray( new IClasspathEntry[0] ), new NullProgressMonitor() ); project.refreshLocal( IResource.DEPTH_INFINITE, new NullProgressMonitor() ); IFolder[] sourceFolders = getSourceFolders(); for( IFolder folder : sourceFolders ) { if( folder.getName().equals( "resources" ) ) { return folder; } } } catch( CoreException e ) { GradleCore.logError( e ); } return null; } @Override public IFile getDescriptorFile( String name ) { return getProject().getFile( name ); } @Override public IPath getLibraryPath( String filename ) { return null; } @Override public IPath getOutputBundle( boolean cleanBuild, IProgressMonitor monitor ) throws CoreException { IPath outputBundlePath = getOutputBundlePath( getProject() ); if( !cleanBuild && outputBundlePath != null && outputBundlePath.toFile().exists() ) { return outputBundlePath; } else { ProjectConnection connection = null; try { GradleConnector connector = GradleConnector.newConnector().forProjectDirectory( getProject().getLocation().toFile() ); connection = connector.connect(); BuildLauncher launcher = connection.newBuild(); BlockingResultHandler<Object> handler = new BlockingResultHandler<>( Object.class ); if( cleanBuild ) { launcher.forTasks( "clean", "build" ).run( handler ); } else { launcher.forTasks( "build" ).run( handler ); } handler.getResult(); } catch( GradleConnectionException e) { GradleCore.logError( "Unable to build output", e ); return null; } finally { connection.close(); } outputBundlePath = getOutputBundlePath( getProject() ); } if( outputBundlePath.toFile().exists() ) { return outputBundlePath; } return null; } @Override public String getProperty( String key, String defaultValue ) { return null; } @Override public String getSymbolicName() throws CoreException { String bsn = ProjectUtil.getBundleSymbolicNameFromBND( getProject() ); if( !CoreUtil.empty( bsn ) ) { return bsn; } String retval = null; final IPath outputBundle = getOutputBundlePath( getProject() ); if( outputBundle == null || outputBundle.lastSegment().endsWith( ".war" ) ) { return getProject().getName(); } else if( outputBundle != null && outputBundle.toFile().exists() ) { try( final Jar jar = new Jar( outputBundle.toFile() ) ) { retval = jar.getBsn(); } catch( Exception e ) { } } return retval; } public boolean isFragmentBundle() { final IFile bndFile = getProject().getFile( "bnd.bnd" ); if( bndFile.exists() ) { try { String content = FileUtil.readContents( bndFile.getContents() ); if( content.contains( "Fragment-Host" ) ) { return true; } } catch( Exception e ) { } } return false; } }