/**
* Copyright 2011 meltmedia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xchain.namespaces.javascript;
import static org.xchain.framework.util.IoUtil.*;
import java.net.URI;
import org.xchain.Command;
import org.xchain.annotations.Attribute;
import org.xchain.annotations.AttributeType;
import org.xchain.annotations.Element;
import org.xchain.annotations.PrefixMapping;
import org.xchain.framework.javascript.BasicMergeStrategy;
import org.xchain.framework.javascript.CacheMergeStrategy;
import org.xchain.framework.javascript.CompressJavaScriptMergeStrategy;
import org.xchain.framework.javascript.IMergeStrategy;
import org.xchain.framework.lifecycle.Execution;
import org.xchain.framework.lifecycle.Lifecycle;
import org.xchain.namespaces.servlet.Constants;
import org.apache.commons.jxpath.JXPathContext;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A basic javascript merging command.
* Will cache results for a merge of the compression flag is set.
*
* @author Mike Moulton
* @author John Trimble
* @author Jason Rose
* @author Josh Kennedy
*/
@Element(localName="merge-javascript")
public abstract class MergeJavascript
implements Command
{
private static Logger log = LoggerFactory.getLogger(MergeJavascript.class);
private static final BasicMergeStrategy BASIC_MERGE_STRATEGY = new BasicMergeStrategy();
@Attribute(
localName="response",
type=AttributeType.JXPATH_VALUE,
defaultValue="$servlet:response",
defaultPrefixMappings={@PrefixMapping(uri=Constants.URI, prefix=Constants.DEFAULT_PREFIX)}
)
public abstract HttpServletResponse getResponse( JXPathContext context );
@Attribute(localName="manifest", type=AttributeType.JXPATH_VALUE)
public abstract String getManifest( JXPathContext context );
@Attribute(localName="compress", defaultValue="'false'", type=AttributeType.JXPATH_VALUE)
public abstract Boolean getCompress( JXPathContext context );
@Attribute(localName="optimization-level", defaultValue="0", type=AttributeType.JXPATH_VALUE)
public abstract Integer getOptimizationLevel( JXPathContext context );
@Attribute(localName="debug", defaultValue="'false'", type=AttributeType.JXPATH_VALUE)
public abstract Boolean getDebugChain( JXPathContext context );
public IMergeStrategy createMergeStrategy( JXPathContext context ) {
// We compress the files if either the compression flag is set and build monitoring is disabled, or the compression
// and debug flags are both set.
if( this.getCompress(context) && ( !Lifecycle.getLifecycleContext().getConfigContext().isMonitored() || getDebugChain(context) ) )
return new CacheMergeStrategy(new CompressJavaScriptMergeStrategy(this.getOptimizationLevel(context)));
return BASIC_MERGE_STRATEGY;
}
public boolean execute( JXPathContext context )
throws Exception
{
IMergeStrategy mergeStrategy = createMergeStrategy(context);
HttpServletResponse response = getResponse(context);
String manifestSystemId = getManifest(context);
if( manifestSystemId == null ) {
return true;
}
// resolve the system id into an absolute URL.
String absoluteManifestSystemId = URI.create(Execution.getSystemId()).resolve(manifestSystemId).toString();
// set the status code to ok.
response.setStatus(HttpServletResponse.SC_OK);
// leave the content type header, it will be set by the pipeline.
response.setContentType("text/javascript");
try {
mergeStrategy.merge(absoluteManifestSystemId, response.getOutputStream());
} finally {
close(response.getOutputStream(), log);
}
// allow other xchains to run.
return true;
}
}