1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.lesscss.internal.compiler

File CachedLESSCompiler.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

12
25
3
1
144
82
11
0.44
8.33
3
3.67

Classes

Class Line # Actions
CachedLESSCompiler 52 25 0% 11 1
0.97597.5%
 

Contributing tests

This file is covered by 5 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.lesscss.internal.compiler;
21   
22    import java.io.StringWriter;
23    import java.util.concurrent.Semaphore;
24   
25    import javax.inject.Inject;
26    import javax.inject.Provider;
27    import javax.inject.Singleton;
28   
29    import org.xwiki.component.annotation.Component;
30    import org.xwiki.component.phase.Initializable;
31    import org.xwiki.component.phase.InitializationException;
32    import org.xwiki.lesscss.compiler.LESSCompilerException;
33    import org.xwiki.lesscss.internal.LESSConfiguration;
34    import org.xwiki.lesscss.internal.cache.CachedCompilerInterface;
35    import org.xwiki.lesscss.internal.compiler.less4j.Less4jCompiler;
36    import org.xwiki.lesscss.internal.resources.LESSSkinFileResourceReference;
37    import org.xwiki.lesscss.resources.LESSResourceReference;
38   
39    import com.github.sommeri.less4j.Less4jException;
40    import com.xpn.xwiki.XWiki;
41    import com.xpn.xwiki.XWikiContext;
42   
43    /**
44    * Compile a LESS resource in a particular context (@see org.xwiki.lesscss.compiler.IntegratedLESSCompiler}.
45    * To be used with AbstractCachedCompiler.
46    *
47    * @since 6.4M2
48    * @version $Id: 4c8cced8b7a9fcf5e6cb1e5513292ed9255d7e38 $
49    */
50    @Component(roles = CachedLESSCompiler.class)
51    @Singleton
 
52    public class CachedLESSCompiler implements CachedCompilerInterface<String>, Initializable
53    {
54    /**
55    * The name of the file holding the main skin style (on which Velocity is always executed).
56    */
57    public static final String MAIN_SKIN_STYLE_FILENAME = "style.less.vm";
58   
59    private static final String SKIN_CONTEXT_KEY = "skin";
60   
61    @Inject
62    private Provider<XWikiContext> xcontextProvider;
63   
64    @Inject
65    private Less4jCompiler less4JCompiler;
66   
67    @Inject
68    private LESSConfiguration lessConfiguration;
69   
70    private Semaphore semaphore;
71   
 
72  34 toggle @Override
73    public void initialize() throws InitializationException
74    {
75  34 this.semaphore = new Semaphore(lessConfiguration.getMaximumSimultaneousCompilations(), true);
76    }
77   
 
78  40 toggle @Override
79    public String compute(LESSResourceReference lessResourceReference, boolean includeSkinStyle, boolean useVelocity,
80    boolean useLESS, String skin) throws LESSCompilerException
81    {
82  40 StringWriter source = new StringWriter();
83   
84  40 try {
85  40 semaphore.acquire();
86  40 if (lessResourceReference instanceof LESSSkinFileResourceReference || includeSkinStyle) {
87   
88  40 if (includeSkinStyle) {
89    // Add the import line to the LESS resource.
90    // We import this file to be able to use variables and mix-ins defined in it.
91    // But we don't want it in the output.
92  2 source.write(String.format("@import (reference) \"%s\";%s", MAIN_SKIN_STYLE_FILENAME,
93    System.lineSeparator()));
94    }
95   
96    // Get the content of the LESS resource
97  40 source.write(lessResourceReference.getContent(skin));
98    }
99   
100    // Parse the LESS content with Velocity
101  40 String lessCode = source.toString();
102  40 if (useVelocity) {
103  38 lessCode = executeVelocity(lessCode, skin);
104    }
105   
106    // Compile the LESS code
107  40 if (useLESS) {
108  39 return less4JCompiler.compile(lessCode, skin, lessConfiguration.isGenerateInlineSourceMaps());
109    }
110   
111    // Otherwise return the raw LESS code
112  1 return lessCode;
113    } catch (Less4jException | InterruptedException e) {
114  1 throw new LESSCompilerException(String.format("Failed to compile the resource [%s] with LESS.",
115    lessResourceReference), e);
116    } finally {
117  40 semaphore.release();
118    }
119    }
120   
 
121  38 toggle private String executeVelocity(String source, String skin)
122    {
123    // Get the XWiki object
124  38 XWikiContext xcontext = xcontextProvider.get();
125  38 XWiki xwiki = xcontext.getWiki();
126  38 String currentSkin = xwiki.getSkin(xcontext);
127   
128  38 try {
129    // Trick: change the current skin in order to compile the LESS file as if the specified skin
130    // was the current skin
131  38 if (!currentSkin.equals(skin)) {
132  2 xcontext.put(SKIN_CONTEXT_KEY, skin);
133    }
134   
135  38 return xwiki.evaluateVelocity(source, xcontext.getDoc().getPrefixedFullName());
136   
137    } finally {
138    // Reset the current skin to the old value
139  38 if (!currentSkin.equals(skin)) {
140  2 xcontext.put(SKIN_CONTEXT_KEY, currentSkin);
141    }
142    }
143    }
144    }