You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2018/07/03 16:44:50 UTC

[sling-org-apache-sling-file-optimization] 03/08: Refactoring the code a bit to make the 'dry-run' not update the actual resource and adding a filter option

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-file-optimization.git

commit d3c9194263a35b336a680787055b8afd51b19659
Author: Dan Klco <dk...@apache.org>
AuthorDate: Mon Jun 4 18:01:23 2018 -0400

    Refactoring the code a bit to make the 'dry-run' not update the actual resource and adding a filter option
---
 pom.xml                                            |   6 ++
 .../sling/fileoptim/FileOptimizerService.java      |  34 +++----
 .../apache/sling/fileoptim/OptimizationResult.java |  42 +++++++-
 .../fileoptim/impl/FileOptimizerEventHandler.java  |  26 ++---
 .../fileoptim/impl/FileOptimizerServiceImpl.java   | 106 ++++++++++----------
 .../impl/filters/FileOptimizerFilter.java          | 109 +++++++++++++++++++++
 .../fileoptim/impl/servlets/FileOptimizerData.java |   3 +-
 .../impl/servlets/FileOptimizerPreview.java        |   2 +-
 .../sling/fileoptim/models/OptimizeResource.java   |  20 +++-
 .../sling/fileoptim/models/OptimizedFile.java      |   9 +-
 src/main/resources/OSGI-INF/l10n/bundle.properties |  14 ++-
 .../resources/SLING-INF/nodetypes/nodetypes.cnd    |   1 +
 12 files changed, 271 insertions(+), 101 deletions(-)

diff --git a/pom.xml b/pom.xml
index d628c44..3d8382d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,12 @@
 			<version>2.3.22</version>
 			<scope>provided</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.engine</artifactId>
+			<version>2.6.12</version>
+			<scope>provided</scope>
+		</dependency>
 
 		<!-- Image Optimization Dependencies -->
 		<dependency>
diff --git a/src/main/java/org/apache/sling/fileoptim/FileOptimizerService.java b/src/main/java/org/apache/sling/fileoptim/FileOptimizerService.java
index c63b43a..9739eb9 100644
--- a/src/main/java/org/apache/sling/fileoptim/FileOptimizerService.java
+++ b/src/main/java/org/apache/sling/fileoptim/FileOptimizerService.java
@@ -17,8 +17,6 @@
 package org.apache.sling.fileoptim;
 
 import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
 
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
@@ -40,6 +38,19 @@ public interface FileOptimizerService {
 	boolean canOptimize(Resource fileResource);
 
 	/**
+	 * Gets the optimized contents of a file resource. This will not update the
+	 * underlying resource, but instead just returns the results of optimizing the
+	 * resource.
+	 * 
+	 * @param fileResource
+	 *            the resource to optimize
+	 * @return the results of the optimization
+	 * @throws IOException
+	 *             an exception occurs reading the original resource
+	 */
+	OptimizationResult getOptimizedContents(Resource fileResource) throws IOException;
+
+	/**
 	 * Returns true if the specified resource has already been optimized by the
 	 * FileOptimizer.
 	 * 
@@ -50,7 +61,7 @@ public interface FileOptimizerService {
 	boolean isOptimized(Resource fileResource);
 
 	/**
-	 * Optimizes a file resource.
+	 * Optimizes a file resource. This method will modify the underlying resource.
 	 * 
 	 * @param fileResource
 	 *            the resource to optimize
@@ -65,21 +76,4 @@ public interface FileOptimizerService {
 	 */
 	OptimizationResult optimizeFile(Resource fileResource, boolean autoCommit) throws PersistenceException, IOException;
 
-	/**
-	 * Optimizes a collection of file resources.
-	 * 
-	 * @param fileResources
-	 *            the resources to optimize
-	 * @param autoCommit
-	 *            if true, the results will automatically be committed to the Sling
-	 *            Repo
-	 * @return the results of the optimization
-	 * @throws PersistenceException
-	 *             an exception occurs saving the optimized resources
-	 * @throws IOException
-	 *             an exception occurs reading the original resources
-	 */
-	Map<String, OptimizationResult> optimizeFiles(Collection<Resource> fileResources, boolean autoCommit)
-			throws PersistenceException, IOException;
-
 }
diff --git a/src/main/java/org/apache/sling/fileoptim/OptimizationResult.java b/src/main/java/org/apache/sling/fileoptim/OptimizationResult.java
index b9ca48b..21de34b 100644
--- a/src/main/java/org/apache/sling/fileoptim/OptimizationResult.java
+++ b/src/main/java/org/apache/sling/fileoptim/OptimizationResult.java
@@ -16,6 +16,9 @@
  */
 package org.apache.sling.fileoptim;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
 import org.apache.sling.api.resource.Resource;
 
 /**
@@ -25,6 +28,7 @@ public class OptimizationResult {
 
 	private String algorithm;
 	private boolean optimized = false;
+	private byte[] optimizedContents;
 	private long optimizedSize;
 	private long originalSize;
 	private final Resource resource;
@@ -35,6 +39,8 @@ public class OptimizationResult {
 	}
 
 	/**
+	 * Returns the algorithm by which the file was optimized
+	 * 
 	 * @return the algorithm
 	 */
 	public String getAlgorithm() {
@@ -42,6 +48,26 @@ public class OptimizationResult {
 	}
 
 	/**
+	 * Returns the raw optimized contents as a byte array
+	 * 
+	 * @return the optimized contents
+	 */
+	public byte[] getOptimizedContents() {
+		return optimizedContents;
+	}
+
+	/**
+	 * Returns the optimized contents as an InputStream
+	 * 
+	 * @return the optimized content stream
+	 */
+	public InputStream getOptimizedContentStream() {
+		return new ByteArrayInputStream(optimizedContents);
+	}
+
+	/**
+	 * Returns the optimized size in bytes
+	 * 
 	 * @return the optimizedSize
 	 */
 	public long getOptimizedSize() {
@@ -49,6 +75,8 @@ public class OptimizationResult {
 	}
 
 	/**
+	 * Return the original size in bytes
+	 * 
 	 * @return the originalSize
 	 */
 	public long getOriginalSize() {
@@ -56,6 +84,8 @@ public class OptimizationResult {
 	}
 
 	/**
+	 * Returns the resource that was optimized
+	 * 
 	 * @return the resource
 	 */
 	public Resource getResource() {
@@ -63,6 +93,8 @@ public class OptimizationResult {
 	}
 
 	/**
+	 * Return the percent savings as a 1-based double value
+	 * 
 	 * @return the savings
 	 */
 	public double getSavings() {
@@ -70,7 +102,11 @@ public class OptimizationResult {
 	}
 
 	/**
-	 * @return the optimized
+	 * Returns true if the result is actually optimized, if the optimization did not
+	 * provide a smaller result or the file was not optimized for any other reason,
+	 * this will be false.
+	 * 
+	 * @return the optimized flag
 	 */
 	public boolean isOptimized() {
 		return optimized;
@@ -92,6 +128,10 @@ public class OptimizationResult {
 		this.optimized = optimized;
 	}
 
+	public void setOptimizedContents(byte[] optimizedContents) {
+		this.optimizedContents = optimizedContents;
+	}
+
 	/**
 	 * @param optimizedSize
 	 *            the optimizedSize to set
diff --git a/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerEventHandler.java b/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerEventHandler.java
index 4803818..5d0364e 100644
--- a/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerEventHandler.java
+++ b/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerEventHandler.java
@@ -27,6 +27,7 @@ import org.apache.sling.fileoptim.FileOptimizerService;
 import org.apache.sling.fileoptim.impl.FileOptimizerEventHandler.Config;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
@@ -42,16 +43,12 @@ import org.slf4j.LoggerFactory;
  * An event filter to trigger to optimize images when they have been saved by
  * compressing.
  */
-@Component(service = EventHandler.class, immediate = true)
+@Component(service = EventHandler.class, immediate = true, configurationPolicy = ConfigurationPolicy.REQUIRE)
 @Designate(ocd = Config.class)
 public class FileOptimizerEventHandler implements EventHandler {
 
 	@ObjectClassDefinition(name = "%event.handler.name", description = "%event.handler.description", localization = "OSGI-INF/l10n/bundle")
 	public @interface Config {
-
-		@AttributeDefinition(name = "%event.handler.enabled.name", description = "%event.handler.enabled.description")
-		boolean enabled() default false;
-
 		@AttributeDefinition(name = "%event.handler.filter.name", description = "%event.handler.filter.description")
 		String event_filter() default "(&(resourceType=sling:File)(|(path=*.png)(path=*.jpg)))";
 
@@ -69,14 +66,11 @@ public class FileOptimizerEventHandler implements EventHandler {
 	@Reference
 	private ResourceResolverFactory rrf;
 
-	private Config config;
-
 	@Activate
 	@Modified
 	public void activate(Config config) throws LoginException {
 		deactivate();
 		resourceResolver = rrf.getServiceResourceResolver(null);
-		this.config = config;
 	}
 
 	@Deactivate
@@ -94,15 +88,13 @@ public class FileOptimizerEventHandler implements EventHandler {
 	 */
 	@Override
 	public void handleEvent(Event event) {
-		if (config.enabled()) {
-			String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
-			Resource fileResource = resourceResolver.getResource(path);
-			if (fileResource != null && fileOptimizer.canOptimize(fileResource)) {
-				try {
-					fileOptimizer.optimizeFile(fileResource, true);
-				} catch (IOException e) {
-					log.error("Exception saving optimized file", e);
-				}
+		String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
+		Resource fileResource = resourceResolver.getResource(path);
+		if (fileResource != null && fileOptimizer.canOptimize(fileResource)) {
+			try {
+				fileOptimizer.optimizeFile(fileResource, true);
+			} catch (IOException e) {
+				log.error("Exception saving optimized file", e);
 			}
 		}
 	}
diff --git a/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerServiceImpl.java b/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerServiceImpl.java
index a1a7807..165d521 100644
--- a/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerServiceImpl.java
+++ b/src/main/java/org/apache/sling/fileoptim/impl/FileOptimizerServiceImpl.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sling.fileoptim.impl;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -116,7 +115,7 @@ public class FileOptimizerServiceImpl implements FileOptimizerService, ServiceLi
 			fileResource = fileResource.getChild(JcrConstants.JCR_CONTENT);
 		}
 		OptimizedFile of = fileResource.adaptTo(OptimizedFile.class);
-		return of != null && fileOptimizers.containsKey(of.getMimeType())
+		return of != null && of.getDisabled() != true && fileOptimizers.containsKey(of.getMimeType())
 				&& fileOptimizers.get(of.getMimeType()).size() > 0;
 	}
 
@@ -132,27 +131,15 @@ public class FileOptimizerServiceImpl implements FileOptimizerService, ServiceLi
 		return fileOptimizers;
 	}
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.apache.sling.fileoptim.FileOptimizerService#getOptimizedContents(org.
+	 * apache.sling.api.resource.Resource)
+	 */
 	@Override
-	public boolean isOptimized(Resource fileResource) {
-
-		if (!fileResource.getName().equals(JcrConstants.JCR_CONTENT)) {
-			fileResource = fileResource.getChild(JcrConstants.JCR_CONTENT);
-		}
-
-		OptimizedFile of = fileResource.adaptTo(OptimizedFile.class);
-		try {
-			String calculatedHash = calculateHash(IOUtils.toByteArray(of.getContent()));
-			log.debug("Comparing stored {} and calculated {} hashes", of.getHash(), calculatedHash);
-			return ObjectUtils.equals(of.getHash(), calculatedHash);
-		} catch (IOException e) {
-			log.error("Exception checking if file optimized, assuming false", e);
-			return false;
-		}
-	}
-
-	@Override
-	public OptimizationResult optimizeFile(Resource fileResource, boolean autoCommit) throws IOException {
-
+	public OptimizationResult getOptimizedContents(Resource fileResource) throws IOException {
 		if (!fileResource.getName().equals(JcrConstants.JCR_CONTENT)) {
 			fileResource = fileResource.getChild(JcrConstants.JCR_CONTENT);
 		}
@@ -178,32 +165,12 @@ public class FileOptimizerServiceImpl implements FileOptimizerService, ServiceLi
 						double savings = 1.0 - ((double) optimized.length / (double) original.length);
 
 						log.debug("Optimized file with {} saving {}%", optimizer.getName(), Math.round(savings * 100));
-
-						ModifiableValueMap mvm = fileResource.adaptTo(ModifiableValueMap.class);
-
-						Set<String> mixins = new HashSet<String>(
-								Arrays.asList(mvm.get(JcrConstants.JCR_MIXINTYPES, new String[0])));
-						mixins.add(OptimizedFile.MT_OPTIMIZED);
-						mvm.put(JcrConstants.JCR_MIXINTYPES, mixins.toArray(new String[] {}));
-
-						mvm.put(OptimizedFile.PN_ALGORITHM, optimizer.getName());
-						mvm.put(OptimizedFile.PN_HASH, calculateHash(optimized));
-						mvm.put(OptimizedFile.PN_ORIGINAL, new ByteArrayInputStream(original));
-						mvm.put(OptimizedFile.PN_SAVINGS, savings);
-						mvm.put(JcrConstants.JCR_DATA, new ByteArrayInputStream(optimized));
-
-						if (autoCommit) {
-							log.debug("Persisting changes...");
-							fileResource.getResourceResolver().commit();
-						}
-
 						result.setAlgorithm(optimizer.getName());
 						result.setSavings(savings);
 						result.setOptimized(true);
 						result.setOptimizedSize(optimized.length);
 						result.setOriginalSize(original.length);
-
-						break;
+						result.setOptimizedContents(optimized);
 					} else {
 						log.debug("Optimizer {} was not able to optimize the file", optimizer.getName());
 					}
@@ -218,22 +185,49 @@ public class FileOptimizerServiceImpl implements FileOptimizerService, ServiceLi
 	}
 
 	@Override
-	public Map<String, OptimizationResult> optimizeFiles(Collection<Resource> fileResources, boolean autoCommit)
-			throws IOException {
-		Map<String, OptimizationResult> results = new HashMap<String, OptimizationResult>();
-		boolean dirty = false;
-		for (Resource fileResource : fileResources) {
-			OptimizationResult res = optimizeFile(fileResource, false);
-			results.put(fileResource.getName(), res);
-			if (res.isOptimized()) {
-				dirty = true;
-			}
+	public boolean isOptimized(Resource fileResource) {
+
+		if (!fileResource.getName().equals(JcrConstants.JCR_CONTENT)) {
+			fileResource = fileResource.getChild(JcrConstants.JCR_CONTENT);
+		}
+
+		OptimizedFile of = fileResource.adaptTo(OptimizedFile.class);
+		try {
+			String calculatedHash = calculateHash(IOUtils.toByteArray(of.getContent()));
+			log.debug("Comparing stored {} and calculated {} hashes", of.getHash(), calculatedHash);
+			return ObjectUtils.equals(of.getHash(), calculatedHash);
+		} catch (IOException e) {
+			log.error("Exception checking if file optimized, assuming false", e);
+			return false;
 		}
-		if (autoCommit && dirty) {
+	}
+
+	@Override
+	public OptimizationResult optimizeFile(Resource fileResource, boolean autoCommit) throws IOException {
+
+		OptimizationResult result = getOptimizedContents(fileResource);
+
+		ModifiableValueMap mvm = fileResource.adaptTo(ModifiableValueMap.class);
+
+		Set<String> mixins = new HashSet<String>(Arrays.asList(mvm.get(JcrConstants.JCR_MIXINTYPES, new String[0])));
+		mixins.add(OptimizedFile.MT_OPTIMIZED);
+		mvm.put(JcrConstants.JCR_MIXINTYPES, mixins.toArray(new String[] {}));
+
+		mvm.put(OptimizedFile.PN_ALGORITHM, result.getAlgorithm());
+		mvm.put(OptimizedFile.PN_HASH, calculateHash(result.getOptimizedContents()));
+		mvm.put(OptimizedFile.PN_ORIGINAL, result.getOptimizedContents());
+		mvm.put(OptimizedFile.PN_SAVINGS, result.getSavings());
+
+		OptimizedFile optim = fileResource.adaptTo(OptimizedFile.class);
+		mvm.put(JcrConstants.JCR_DATA, IOUtils.toByteArray(optim.getContent()));
+
+		if (autoCommit) {
 			log.debug("Persisting changes...");
-			fileResources.iterator().next().getResourceResolver().commit();
+			fileResource.getResourceResolver().commit();
 		}
-		return results;
+
+		return result;
+
 	}
 
 	private void rebuildOptimizerCache() {
diff --git a/src/main/java/org/apache/sling/fileoptim/impl/filters/FileOptimizerFilter.java b/src/main/java/org/apache/sling/fileoptim/impl/filters/FileOptimizerFilter.java
new file mode 100644
index 0000000..466c212
--- /dev/null
+++ b/src/main/java/org/apache/sling/fileoptim/impl/filters/FileOptimizerFilter.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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.apache.sling.fileoptim.impl.filters;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.engine.EngineConstants;
+import org.apache.sling.fileoptim.FileOptimizerService;
+import org.apache.sling.fileoptim.OptimizationResult;
+import org.apache.sling.fileoptim.impl.filters.FileOptimizerFilter.Config;
+import org.apache.sling.fileoptim.models.OptimizedFile;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Sling Servlet Filter for optimizing a file response.
+ */
+@Component(service = { Filter.class }, property = { "sling.filter.scope="
+		+ EngineConstants.FILTER_SCOPE_REQUEST }, configurationPolicy = ConfigurationPolicy.REQUIRE)
+@Designate(ocd = Config.class)
+public class FileOptimizerFilter implements Filter {
+
+	@ObjectClassDefinition(name = "%filter.name", description = "%filter.description", localization = "OSGI-INF/l10n/bundle")
+	public @interface Config {
+
+		@AttributeDefinition(name = "%filter.pattern.name", description = "%filter.pattern.description")
+		String sling_filter_pattern() default "-";
+
+		@AttributeDefinition(name = "%filter.service.ranking.name", description = "%filter.service.ranking.name")
+		int service_ranking() default 0;
+
+	}
+
+	private static final Logger log = LoggerFactory.getLogger(FileOptimizerFilter.class);
+
+	@Reference
+	private FileOptimizerService fileOptimizer;
+
+	@Override
+	public void init(FilterConfig filterConfig) throws ServletException {
+	}
+
+	@Override
+	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+			throws IOException, ServletException {
+		if (request instanceof SlingHttpServletRequest) {
+			Resource resource = ((SlingHttpServletRequest) request).getResource();
+			try {
+				if (fileOptimizer.canOptimize(resource)) {
+					log.debug("Returning optimized file");
+					OptimizationResult res = fileOptimizer.getOptimizedContents(resource);
+					if (res.isOptimized()) {
+						OptimizedFile of = null;
+						if (!resource.getName().equals(JcrConstants.JCR_CONTENT)) {
+							of = resource.getChild(JcrConstants.JCR_CONTENT).adaptTo(OptimizedFile.class);
+						} else {
+							of = resource.adaptTo(OptimizedFile.class);
+						}
+						response.setContentType(of.getMimeType());
+						response.setContentLengthLong(res.getOptimizedSize());
+						((HttpServletResponse) response).setHeader("Optimized-With", res.getAlgorithm());
+						IOUtils.copy(res.getOptimizedContentStream(), response.getOutputStream());
+						return;
+					}
+				}
+			} catch (Exception e) {
+				log.warn("Unexpected exception attempting to optimize file response", e);
+			}
+		}
+		chain.doFilter(request, response);
+	}
+
+	@Override
+	public void destroy() {
+	}
+
+}
diff --git a/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerData.java b/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerData.java
index 639be70..ff7b986 100644
--- a/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerData.java
+++ b/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerData.java
@@ -23,7 +23,6 @@ import javax.json.stream.JsonGenerator;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 
-import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
@@ -55,7 +54,7 @@ public class FileOptimizerData extends SlingSafeMethodsServlet {
 			response.sendError(404, "No Resource found at path " + path);
 		} else if (fileOptimizer.canOptimize(resource)) {
 
-			OptimizationResult res = fileOptimizer.optimizeFile(resource.getChild(JcrConstants.JCR_CONTENT), false);
+			OptimizationResult res = fileOptimizer.getOptimizedContents(resource);
 			response.setContentType("application/json");
 
 			JsonGenerator json = Json.createGenerator(response.getWriter());
diff --git a/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerPreview.java b/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerPreview.java
index 53bf7e5..3786097 100644
--- a/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerPreview.java
+++ b/src/main/java/org/apache/sling/fileoptim/impl/servlets/FileOptimizerPreview.java
@@ -55,7 +55,7 @@ public class FileOptimizerPreview extends SlingSafeMethodsServlet {
 		if (resource == null) {
 			response.sendError(404, "No Resource found at path " + path);
 		} else if (fileOptimizer.canOptimize(resource)) {
-			OptimizationResult res = fileOptimizer.optimizeFile(resource.getChild(JcrConstants.JCR_CONTENT), false);
+			OptimizationResult res = fileOptimizer.getOptimizedContents(resource);
 			ValueMap vm = res.getResource().getValueMap();
 			response.setContentType(vm.get(JcrConstants.JCR_MIMETYPE, String.class));
 			response.setHeader("Content-disposition", "inline; filename=" + resource.getName());
diff --git a/src/main/java/org/apache/sling/fileoptim/models/OptimizeResource.java b/src/main/java/org/apache/sling/fileoptim/models/OptimizeResource.java
index 2960d1a..218929a 100644
--- a/src/main/java/org/apache/sling/fileoptim/models/OptimizeResource.java
+++ b/src/main/java/org/apache/sling/fileoptim/models/OptimizeResource.java
@@ -30,7 +30,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Sling model for executing the optimizer, will not commit the result
+ * Sling model for executing the optimizer on a resource, will not commit the
+ * result
  */
 @Model(adaptables = Resource.class)
 public class OptimizeResource {
@@ -55,21 +56,36 @@ public class OptimizeResource {
 		log.debug("initializing with resource {}", resource);
 		if (fileOptimizer.canOptimize(resource)) {
 			this.canOptimize = true;
-			this.result = fileOptimizer.optimizeFile(resource, false);
+			this.result = fileOptimizer.getOptimizedContents(resource);
 		} else {
 			this.canOptimize = false;
 			this.result = null;
 		}
 	}
 
+	/**
+	 * Returns true if the file is optimized, false otherwise
+	 * 
+	 * @return
+	 */
 	public boolean isOptimized() {
 		return fileOptimizer.isOptimized(resource);
 	}
 
+	/**
+	 * Gets the optimization result.
+	 * 
+	 * @return
+	 */
 	public OptimizationResult getResult() {
 		return result;
 	}
 
+	/**
+	 * Return true if the file can be optimized
+	 * 
+	 * @return
+	 */
 	public boolean isCanOptimize() {
 		return canOptimize;
 	}
diff --git a/src/main/java/org/apache/sling/fileoptim/models/OptimizedFile.java b/src/main/java/org/apache/sling/fileoptim/models/OptimizedFile.java
index 12a0e66..061701b 100644
--- a/src/main/java/org/apache/sling/fileoptim/models/OptimizedFile.java
+++ b/src/main/java/org/apache/sling/fileoptim/models/OptimizedFile.java
@@ -23,12 +23,13 @@ import javax.inject.Named;
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Default;
 import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.annotations.Required;
 
 /**
- * Sling Model representing an optimized file
+ * Sling Model representing a file which can be or has been optimized.
  */
 @Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
 public interface OptimizedFile {
@@ -36,6 +37,7 @@ public interface OptimizedFile {
 	static final String PREFIX = "optim:";
 	public static final String MT_OPTIMIZED = PREFIX + "optimized";
 	public static final String PN_ALGORITHM = PREFIX + "algrithm";
+	public static final String PN_DISABLED = PREFIX + "disabled";
 	public static final String PN_HASH = PREFIX + "hash";
 	public static final String PN_ORIGINAL = PREFIX + "original";
 	public static final String PN_SAVINGS = PREFIX + "savings";
@@ -44,6 +46,11 @@ public interface OptimizedFile {
 	@Inject
 	String getAlgorithm();
 
+	@Named(PN_DISABLED)
+	@Inject
+	@Default(booleanValues = false)
+	boolean getDisabled();
+
 	@Named(JcrConstants.JCR_DATA)
 	@Inject
 	@Required
diff --git a/src/main/resources/OSGI-INF/l10n/bundle.properties b/src/main/resources/OSGI-INF/l10n/bundle.properties
index 66e75e6..5c5849a 100644
--- a/src/main/resources/OSGI-INF/l10n/bundle.properties
+++ b/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -49,4 +49,16 @@ jpeg.optimizer.name=Apache Sling JPEG Optimizer
 jpeg.optimizer.description=An optimizer for lossily compressing JPEG images
 
 jpeg.optimizer.compression.level.name=Compression Level
-jpeg.optimizer.compression.level.description=The compression level for compressing the Jpeg (between 0.0 - 1.0)
\ No newline at end of file
+jpeg.optimizer.compression.level.description=The compression level for compressing the Jpeg (between 0.0 - 1.0)
+
+# Filter Keys
+
+filter.name=Apache Sling File Optimizer Filter
+filter.description=Sling Servlet Filter for optimizing a file response
+
+filter.pattern.name=Filter Pattern
+filter.pattern.description=Restrict the filter to paths that match the supplied regular expression
+
+filter.service.ranking.name=Service Ranking
+filter.service.ranking.description=Indication of where to place the filter in the filter chain. The higher the number the \
+earlier in the filter chain.
\ No newline at end of file
diff --git a/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd b/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
index 204b4b6..f572c95 100644
--- a/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
+++ b/src/main/resources/SLING-INF/nodetypes/nodetypes.cnd
@@ -27,6 +27,7 @@
 [optim:optimized] 
  mixin  
  - optim:algorithm (string)
+ - optim:disabled (boolean)
  - optim:hash (string)
  - optim:original (binary)
  - optim:savings (double)
\ No newline at end of file