/******************************************************************************* * 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.theme.core; import com.liferay.ide.core.ILiferayConstants; import com.liferay.ide.core.ILiferayPortal; import com.liferay.ide.core.ILiferayProject; import com.liferay.ide.core.IWebProject; import com.liferay.ide.core.LiferayCore; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.core.util.StringPool; import com.liferay.ide.project.core.facet.IPluginProjectDataModelProperties; import com.liferay.ide.sdk.core.ISDKConstants; import com.liferay.ide.sdk.core.SDK; import com.liferay.ide.sdk.core.SDKUtil; import com.liferay.ide.theme.core.operation.ThemeDescriptorHelper; import com.liferay.ide.theme.core.util.BuildHelper; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; 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.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; /** * @author Gregory Amerson * @author Cindy Li */ @SuppressWarnings( "rawtypes" ) public class ThemeCSSBuilder extends IncrementalProjectBuilder { public static final String ID = "com.liferay.ide.eclipse.theme.core.cssBuilder"; //$NON-NLS-1$ public static IStatus compileTheme( IProject project ) throws CoreException { final SDK sdk = SDKUtil.getSDK( project ); if( sdk == null ) { throw new CoreException( ThemeCore.createErrorStatus( "No SDK for project configured. Could not build theme." ) ); //$NON-NLS-1$ } final IStatus status = sdk.compileThemePlugin( project, null ); if( !status.isOK() ) { throw new CoreException( status ); } ensureLookAndFeelFileExists( project ); try { project.refreshLocal( IResource.DEPTH_INFINITE, null ); } catch( Exception e ) { ThemeCore.logError( e ); } return status; } public static void ensureLookAndFeelFileExists( IProject project ) throws CoreException { // IDE-110 IDE-648 final IWebProject lrProject = LiferayCore.create( IWebProject.class, project ); if( lrProject == null ) { return; } IFile lookAndFeelFile = null; final IResource res = lrProject.findDocrootResource( new Path( "WEB-INF/" + ILiferayConstants.LIFERAY_LOOK_AND_FEEL_XML_FILE ) ); if( res instanceof IFile && res.exists() ) { lookAndFeelFile = (IFile) res; } if( lookAndFeelFile == null ) { // need to generate a new lnf file in deafult docroot String id = project.getName().replaceAll( ISDKConstants.THEME_PLUGIN_PROJECT_SUFFIX, StringPool.EMPTY ); final IResource propertiesFileRes = lrProject.findDocrootResource( new Path( "WEB-INF/" + ILiferayConstants.LIFERAY_PLUGIN_PACKAGE_PROPERTIES_FILE ) ); String name = id; if( propertiesFileRes instanceof IFile && propertiesFileRes.exists() ) { Properties props = new Properties(); try { final IFile propsFile = (IFile) propertiesFileRes; final InputStream contents = propsFile.getContents(); props.load( contents ); contents.close(); final String nameValue = props.getProperty( "name" ); //$NON-NLS-1$ if( !CoreUtil.isNullOrEmpty( nameValue ) ) { name = nameValue; } final ThemeDescriptorHelper themeDescriptorHelper = new ThemeDescriptorHelper( project ); final ILiferayProject lProject = lrProject; final ILiferayPortal portal = lProject.adapt( ILiferayPortal.class ); String version = "6.2.0"; if( portal != null ) { version = portal.getVersion(); } final String themeType = lProject.getProperty( "theme.type", "vm" ); themeDescriptorHelper.createDefaultFile( lrProject.getDefaultDocrootFolder().getFolder( "WEB-INF" ), version, id, name, themeType ); } catch( IOException e ) { ThemeCore.logError( "Unable to load plugin package properties.", e ); //$NON-NLS-1$ } } } } private BuildHelper buildHelper; public ThemeCSSBuilder() { super(); this.buildHelper = new BuildHelper(); } protected void applyDiffsDeltaToDocroot( final IResourceDelta delta, final IContainer docroot, final IProgressMonitor monitor ) { int deltaKind = delta.getKind(); switch( deltaKind ) { case IResourceDelta.REMOVED_PHANTOM: break; } final IPath path = CoreUtil.getResourceLocation( docroot ); // final IPath restoreLocation = getRestoreLocation(docroot); final ILiferayProject liferayProject = LiferayCore.create( getProject() ); final String themeParent = liferayProject.getProperty( "theme.parent", "_styled" ); final ILiferayPortal portal = liferayProject.adapt( ILiferayPortal.class ); if( portal != null ) { final IPath themesPath = portal.getAppServerPortalDir().append( "html/themes" ); final List<IPath> restorePaths = new ArrayList<IPath>(); for( int i = 0; i < IPluginProjectDataModelProperties.THEME_PARENTS.length; i++ ) { if( IPluginProjectDataModelProperties.THEME_PARENTS[i].equals( themeParent ) ) { restorePaths.add( themesPath.append( IPluginProjectDataModelProperties.THEME_PARENTS[i] ) ); } else { if( restorePaths.size() > 0 ) { restorePaths.add( themesPath.append( IPluginProjectDataModelProperties.THEME_PARENTS[i] ) ); } } } new Job( "publish theme delta" ) //$NON-NLS-1$ { @Override protected IStatus run( IProgressMonitor monitor ) { buildHelper.publishDelta( delta, path, restorePaths.toArray( new IPath[0] ), monitor ); try { docroot.refreshLocal( IResource.DEPTH_INFINITE, monitor ); } catch( Exception e ) { ThemeCore.logError( e ); } return Status.OK_STATUS; } }.schedule(); } } @Override protected IProject[] build( int kind, Map args, IProgressMonitor monitor ) { if( kind == IncrementalProjectBuilder.FULL_BUILD ) { fullBuild( args, monitor ); } else { IResourceDelta delta = getDelta( getProject() ); if( delta == null ) { fullBuild( args, monitor ); } else { incrementalBuild( delta, monitor ); } } return null; } protected void fullBuild( Map args, IProgressMonitor monitor ) { try { if( shouldFullBuild( args ) ) { compileTheme( getProject( args ) ); } } catch( Exception e ) { ThemeCore.logError( "Full build failed for Theme CSS Builder", e ); //$NON-NLS-1$ } } protected IProject getProject( Map args ) { return this.getProject(); } protected void incrementalBuild( IResourceDelta delta, final IProgressMonitor monitor ) { int deltaKind = delta.getKind(); if( deltaKind == IResourceDelta.REMOVED ) { return; } // final boolean[] buildCSS = new boolean[1]; try { delta.accept( new IResourceDeltaVisitor() { public boolean visit( IResourceDelta delta ) { final IResource resource = delta.getResource(); IPath fullResourcePath = resource.getFullPath(); for( String segment : fullResourcePath.segments() ) { if( "_diffs".equals( segment ) ) //$NON-NLS-1$ { // IDE-110 IDE-648 final IWebProject webproject = LiferayCore.create( IWebProject.class, getProject() ); if( webproject != null && webproject.getDefaultDocrootFolder() != null ) { IFolder webappRoot = webproject.getDefaultDocrootFolder(); if( webappRoot != null ) { IFolder diffs = webappRoot.getFolder( new Path( "_diffs" ) ); //$NON-NLS-1$ if( diffs != null && diffs.exists() && diffs.getFullPath().isPrefixOf( fullResourcePath ) ) { applyDiffsDeltaToDocroot( delta, diffs.getParent(), monitor ); return false; } } } } else if( "build.xml".equals( segment ) ) //IDE-828 //$NON-NLS-1$ { IPath relPath = resource.getProjectRelativePath(); if( relPath != null && relPath.segmentCount() == 1 ) { try { compileTheme( resource.getProject() ); } catch( CoreException e ) { ThemeCore.logError( "Error compiling theme.", e ); //$NON-NLS-1$ } } } } return true; // visit children too } } ); } catch( CoreException e ) { ThemeCore.logError( e ); } } protected boolean shouldFullBuild( Map args ) throws CoreException { if( args != null && args.get( "force" ) != null && args.get( "force" ).equals( "true" ) ) { return true; } // check to see if there is any files in the _diffs folder // IDE-110 IDE-648 final IWebProject lrproject = LiferayCore.create( IWebProject.class, getProject() ); if( lrproject != null && lrproject.getDefaultDocrootFolder() != null ) { final IFolder webappRoot = lrproject.getDefaultDocrootFolder(); if( webappRoot != null ) { IFolder diffs = webappRoot.getFolder( new Path( "_diffs" ) ); if( diffs != null && diffs.exists() ) { IResource[] diffMembers = diffs.members(); if( !CoreUtil.isNullOrEmpty( diffMembers ) ) { return true; } } } } return false; } }