/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This 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 software 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. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.lesscss; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import org.apache.commons.lang3.exception.ExceptionUtils; import org.xwiki.component.annotation.Component; import org.xwiki.lesscss.compiler.LESSCompiler; import org.xwiki.lesscss.compiler.LESSCompilerException; import org.xwiki.lesscss.internal.cache.ColorThemeCache; import org.xwiki.lesscss.internal.cache.LESSResourcesCache; import org.xwiki.lesscss.internal.colortheme.ColorTheme; import org.xwiki.lesscss.internal.colortheme.ColorThemeReference; import org.xwiki.lesscss.internal.colortheme.ColorThemeReferenceFactory; import org.xwiki.lesscss.internal.colortheme.LESSColorThemeConverter; import org.xwiki.lesscss.internal.skin.SkinReference; import org.xwiki.lesscss.internal.skin.SkinReferenceFactory; import org.xwiki.lesscss.resources.LESSResourceReferenceFactory; import org.xwiki.script.service.ScriptService; import org.xwiki.security.authorization.AuthorizationManager; import org.xwiki.security.authorization.Right; import com.xpn.xwiki.XWikiContext; /** * This script service provides a LESS preprocessor (http://lesscss.org/) for CSS generation. * * @since 6.1M1 * @version $Id: c053329ca675059d02e6061287fe3b38fc3aee82 $ */ @Component @Named("lesscss") @Singleton public class LessCompilerScriptService implements ScriptService { @Inject private LESSCompiler lessCompiler; @Inject private LESSResourceReferenceFactory lessResourceReferenceFactory; @Inject private LESSResourcesCache lessCache; @Inject private ColorThemeCache colorThemeCache; @Inject private Provider<XWikiContext> xcontextProvider; @Inject private LESSColorThemeConverter lessColorThemeConverter; @Inject private SkinReferenceFactory skinReferenceFactory; @Inject private ColorThemeReferenceFactory colorThemeReferenceFactory; @Inject private AuthorizationManager authorizationManager; /** * Compile a LESS file located in the "less" directory of the current skin directory. * Velocity will also be parsed on the file, but not on the files included via the @import directive. * The result is cached by XWiki until the skin or the color theme is changed. * * @param fileName name of the file to compile * @return the generated CSS, or an error message if some problem occurs */ public String compileSkinFile(String fileName) { return compileSkinFile(fileName, false); } /** * Compile a LESS file located in the "less" directory of the current skin directory. * Velocity will also be parsed on the file, but not on the files included via the @import directive. * The result is cached by XWiki until the skin or the color theme is changed. * * @param fileName name of the file to compile * @param force force the computation, even if the output is already in the cache (not recommended) * @return the generated CSS, or an error message if some problem occurs */ public String compileSkinFile(String fileName, boolean force) { try { return lessCompiler.compile(lessResourceReferenceFactory.createReferenceForSkinFile(fileName), false, true, force); } catch (LESSCompilerException e) { return ExceptionUtils.getRootCauseMessage(e); } } /** * Compile a LESS file located in the "less" directory of the specified skin directory. * Velocity will also be parsed on the file, but not on the files included via the @import directive. * The result is cached by XWiki until the skin or the color theme is changed. * * @param fileName name of the file to compile * @param skin name of the skin where the LESS file is located * @return the generated CSS, or an error message if some problem occurs */ public String compileSkinFile(String fileName, String skin) { return compileSkinFile(fileName, skin, false); } /** * Compile a LESS file located in the "less" directory of the specified skin directory. * Velocity will also be parsed on the file, but not on the files included via the @import directive. * The result is cached by XWiki until the skin or the color theme is changed. * * @param fileName name of the file to compile * @param skin name of the skin where the LESS file is located * @param force force the computation, even if the output is already in the cache (not recommended) * @return the generated CSS, or an error message if some problem occurs */ public String compileSkinFile(String fileName, String skin, boolean force) { try { return lessCompiler.compile(lessResourceReferenceFactory.createReferenceForSkinFile(fileName), false, true, skin, force); } catch (LESSCompilerException e) { return ExceptionUtils.getRootCauseMessage(e); } } /** * Return a color theme from a LESS file located in the "less" directory of the current skin. * * @param filename name of the LESS file * @return the corresponding Color Theme. */ public ColorTheme getColorThemeFromSkinFile(String filename) { try { return lessColorThemeConverter.getColorThemeFromSkinFile(filename, false); } catch (LESSCompilerException e) { return new ColorTheme(); } } /** * Return a color theme from a LESS file located in the "less" directory of the specified skin. * * @param filename name of the LESS file * @param skin name of the skin where the LESS file is located * @return the corresponding Color Theme. */ public ColorTheme getColorThemeFromSkinFile(String filename, String skin) { try { return lessColorThemeConverter.getColorThemeFromSkinFile(filename, skin, false); } catch (LESSCompilerException e) { return new ColorTheme(); } } /** * Remove every generated files from the XWiki cache. The script calling this method needs the programming rights. * @return true if the operation succeed */ public boolean clearCache() { XWikiContext xcontext = xcontextProvider.get(); // Check if the current script has the programing rights if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(), xcontext.getDoc().getDocumentReference())) { return false; } lessCache.clear(); colorThemeCache.clear(); return true; } /** * Remove every generated files corresponding to a color theme. * The script calling this method needs the programming rights. * @param colorTheme fullname of the color theme * @return true if the operation succeed */ public boolean clearCacheFromColorTheme(String colorTheme) { XWikiContext xcontext = xcontextProvider.get(); // Check if the current script has the programing rights if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(), xcontext.getDoc().getDocumentReference())) { return false; } try { ColorThemeReference colorThemeReference = colorThemeReferenceFactory.createReference(colorTheme); lessCache.clearFromColorTheme(colorThemeReference); colorThemeCache.clearFromColorTheme(colorThemeReference); return true; } catch (LESSCompilerException e) { return false; } } /** * Remove every generated files corresponding to a filesystem skin. * The script calling this method needs the programming rights. * @param skin name of the filesystem skin * @return true if the operation succeed * * @since 6.4M2 */ public boolean clearCacheFromSkin(String skin) { XWikiContext xcontext = xcontextProvider.get(); // Check if the current script has the programing rights if (!authorizationManager.hasAccess(Right.PROGRAM, xcontext.getDoc().getAuthorReference(), xcontext.getDoc().getDocumentReference())) { return false; } try { SkinReference skinReference = skinReferenceFactory.createReference(skin); lessCache.clearFromSkin(skinReference); colorThemeCache.clearFromSkin(skinReference); return true; } catch (LESSCompilerException e) { return false; } } }