You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by jh...@apache.org on 2005/11/03 15:00:48 UTC
svn commit: r330548 [50/132] - in
/cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/
cocoon-ajax-block/api/ cocoon-ajax-block/api/src/
cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/
cocoon-ajax-block/api/src/main/...
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/WildcardURIMatcher.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/WildcardURIMatcher.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/WildcardURIMatcher.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/WildcardURIMatcher.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Match the request URI against a wildcard expression.
+ *
+ * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @version CVS $Id: WildcardURIMatcher.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public class WildcardURIMatcher extends AbstractWildcardMatcher
+{
+ /**
+ * Return the request URI.
+ */
+ protected String getMatchString(Map objectModel, Parameters parameters) {
+ String uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+
+ if (uri.startsWith("/")) {
+ uri = uri.substring(1);
+ }
+
+ return uri;
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/WildcardURIMatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,385 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.matching.helpers;
+
+import java.util.HashMap;
+
+/**
+ * This class is an utility class that perform wilcard-patterns matching and
+ * isolation.
+ *
+ * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
+ * (Apache Software Foundation)
+ * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
+ * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
+ * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
+ * @version CVS $Id: WildcardHelper.java 160568 2005-04-08 17:33:05Z sylvain $
+ */
+public class WildcardHelper {
+
+ /** The int representing '*' in the pattern <code>int []</code>. */
+ protected static final int MATCH_FILE = -1;
+ /** The int representing '**' in the pattern <code>int []</code>. */
+ protected static final int MATCH_PATH = -2;
+ /** The int representing begin in the pattern <code>int []</code>. */
+ protected static final int MATCH_BEGIN = -4;
+ /** The int representing end in pattern <code>int []</code>. */
+ protected static final int MATCH_THEEND = -5;
+ /** The int value that terminates the pattern <code>int []</code>. */
+ protected static final int MATCH_END = -3;
+
+
+ /**
+ * Translate the given <code>String</code> into a <code>int []</code>
+ * representing the pattern matchable by this class.
+ * <br>
+ * This function translates a <code>String</code> into an int array
+ * converting the special '*' and '\' characters.
+ * <br>
+ * Here is how the conversion algorithm works:
+ * <ul>
+ * <li>The '*' character is converted to MATCH_FILE, meaning that zero
+ * or more characters (excluding the path separator '/') are to
+ * be matched.</li>
+ * <li>The '**' sequence is converted to MATCH_PATH, meaning that zero
+ * or more characters (including the path separator '/') are to
+ * be matched.</li>
+ * <li>The '\' character is used as an escape sequence ('\*' is
+ * translated in '*', not in MATCH_FILE). If an exact '\' character
+ * is to be matched the source string must contain a '\\'.
+ * sequence.</li>
+ * </ul>
+ * When more than two '*' characters, not separated by another character,
+ * are found their value is considered as '**' (MATCH_PATH).
+ * <br>
+ * The array is always terminated by a special value (MATCH_END).
+ * <br>
+ * All MATCH* values are less than zero, while normal characters are equal
+ * or greater.
+ *
+ * @param data The string to translate.
+ * @return The encoded string as an int array, terminated by the MATCH_END
+ * value (don't consider the array length).
+ * @exception NullPointerException If data is null.
+ */
+ public static int[] compilePattern(String data)
+ throws NullPointerException {
+
+ // Prepare the arrays
+ int expr[] = new int[data.length() + 2];
+ char buff[] = data.toCharArray();
+
+ // Prepare variables for the translation loop
+ int y = 0;
+ boolean slash = false;
+
+ // Must start from beginning
+ expr[y++] = MATCH_BEGIN;
+
+ if (buff.length > 0) {
+ if (buff[0]=='\\') {
+ slash = true;
+ } else if (buff[0] == '*') {
+ expr[y++] = MATCH_FILE;
+ } else {
+ expr[y++] = buff[0];
+ }
+
+ // Main translation loop
+ for (int x = 1; x < buff.length; x++) {
+ // If the previous char was '\' simply copy this char.
+ if (slash) {
+ expr[y++] = buff[x];
+ slash = false;
+ // If the previous char was not '\' we have to do a bunch of checks
+ } else {
+ // If this char is '\' declare that and continue
+ if (buff[x] == '\\') {
+ slash = true;
+ // If this char is '*' check the previous one
+ } else if (buff[x] == '*') {
+ // If the previous character als was '*' match a path
+ if (expr[y-1] <= MATCH_FILE) {
+ expr[y-1] = MATCH_PATH;
+ } else {
+ expr[y++] = MATCH_FILE;
+ }
+ } else {
+ expr[y++]=buff[x];
+ }
+ }
+ }
+ }
+
+ // Must match end at the end
+ expr[y] = MATCH_THEEND;
+ return expr;
+ }
+
+ /**
+ * match a pattern agains a string and isolates wildcard replacement into a
+ * <code>Stack</code>.
+ */
+ public static boolean match (HashMap map, String data, int[] expr)
+ throws NullPointerException {
+ if (data == null) {
+ throw new NullPointerException ("No data provided");
+ }
+ if (expr == null) {
+ throw new NullPointerException ("No pattern expression provided");
+ }
+
+
+ char buff[] = data.toCharArray();
+ // Allocate the result buffer
+ char rslt[] = new char[expr.length + buff.length];
+
+
+ // The previous and current position of the expression character
+ // (MATCH_*)
+ int charpos = 0;
+
+ // The position in the expression, input, translation and result arrays
+ int exprpos = 0;
+ int buffpos = 0;
+ int rsltpos = 0;
+ int offset = -1;
+
+ // The matching count
+ int mcount = 0;
+
+ if ( map != null ) {
+ // We want the complete data be in {0}
+ map.put(Integer.toString(mcount),data);
+ }
+
+ // First check for MATCH_BEGIN
+ boolean matchBegin = false;
+ if (expr[charpos] == MATCH_BEGIN) {
+ matchBegin = true;
+ exprpos = ++charpos;
+ }
+
+ // Search the fist expression character (except MATCH_BEGIN - already skipped)
+ while (expr[charpos] >= 0)
+ charpos++;
+
+ // The expression charater (MATCH_*)
+ int exprchr = expr[charpos];
+
+ while (true) {
+ // Check if the data in the expression array before the current
+ // expression character matches the data in the input buffer
+ if (matchBegin) {
+ if (!matchArray(expr, exprpos, charpos, buff, buffpos))
+ return (false);
+ matchBegin = false;
+ } else {
+ offset = indexOfArray (expr, exprpos, charpos, buff,
+ buffpos);
+ if (offset < 0)
+ return (false);
+ }
+
+ // Check for MATCH_BEGIN
+ if (matchBegin) {
+ if (offset != 0)
+ return (false);
+ matchBegin = false;
+ }
+
+ // Advance buffpos
+ buffpos += (charpos - exprpos);
+
+ // Check for END's
+ if (exprchr == MATCH_END) {
+ if (rsltpos > 0 && map != null) {
+ map.put(Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+ }
+ // Don't care about rest of input buffer
+ return (true);
+ } else if (exprchr == MATCH_THEEND) {
+ if (rsltpos > 0 && map != null ) {
+ map.put (Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+ }
+ // Check that we reach buffer's end
+ return (buffpos == buff.length);
+ }
+
+ // Search the next expression character
+ exprpos = ++charpos;
+ while (expr[charpos] >= 0)
+ charpos++;
+ int prevchr = exprchr;
+ exprchr = expr[charpos];
+
+ // We have here prevchr == * or **.
+ offset = (prevchr == MATCH_FILE) ?
+ indexOfArray (expr, exprpos, charpos, buff, buffpos) :
+ lastIndexOfArray (expr, exprpos, charpos, buff,
+ buffpos);
+
+ if (offset < 0)
+ return (false);
+
+ // Copy the data from the source buffer into the result buffer
+ // to substitute the expression character
+ if (prevchr == MATCH_PATH) {
+ while (buffpos < offset)
+ rslt[rsltpos++] = buff[buffpos++];
+ } else {
+ // Matching file, don't copy '/'
+ while (buffpos < offset) {
+ if (buff[buffpos] == '/')
+ return (false);
+ rslt[rsltpos++] = buff[buffpos++];
+ }
+ }
+
+ if ( map != null ) {
+ map.put(Integer.toString(++mcount),new String (rslt, 0, rsltpos));
+ }
+ rsltpos = 0;
+ }
+ }
+
+ /**
+ * Get the offset of a part of an int array within a char array.
+ * <br>
+ * This method return the index in d of the first occurrence after dpos of
+ * that part of array specified by r, starting at rpos and terminating at
+ * rend.
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param rend The index of the last character in r to look for plus 1.
+ * @param d The array of char that should contain a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return The offset in d of the part of r matched in d or -1 if that was
+ * not found.
+ */
+ protected static int indexOfArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ // Check if pos and len are legal
+ if (rend < rpos)
+ throw new IllegalArgumentException ("rend < rpos");
+ // If we need to match a zero length string return current dpos
+ if (rend == rpos)
+ return (d.length); //?? dpos?
+ // If we need to match a 1 char length string do it simply
+ if ((rend - rpos) == 1) {
+ // Search for the specified character
+ for (int x = dpos; x < d.length; x++)
+ if (r[rpos] == d[x])
+ return (x);
+ }
+ // Main string matching loop. It gets executed if the characters to
+ // match are less then the characters left in the d buffer
+ while ((dpos + rend - rpos) <= d.length) {
+ // Set current startpoint in d
+ int y = dpos;
+ // Check every character in d for equity. If the string is matched
+ // return dpos
+ for (int x = rpos; x <= rend; x++) {
+ if (x == rend)
+ return (dpos);
+ if (r[x] != d[y++])
+ break;
+ }
+ // Increase dpos to search for the same string at next offset
+ dpos++;
+ }
+ // The remaining chars in d buffer were not enough or the string
+ // wasn't matched
+ return (-1);
+ }
+
+ /**
+ * Get the offset of a last occurance of an int array within a char array.
+ * <br>
+ * This method return the index in d of the last occurrence after dpos of
+ * that part of array specified by r, starting at rpos and terminating at
+ * rend.
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param rend The index of the last character in r to look for plus 1.
+ * @param d The array of char that should contain a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return The offset in d of the last part of r matched in d or -1 if that was
+ * not found.
+ */
+ protected static int lastIndexOfArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ // Check if pos and len are legal
+ if (rend < rpos)
+ throw new IllegalArgumentException ("rend < rpos");
+ // If we need to match a zero length string return current dpos
+ if (rend == rpos)
+ return (d.length); //?? dpos?
+
+ // If we need to match a 1 char length string do it simply
+ if ((rend - rpos) == 1) {
+ // Search for the specified character
+ for (int x = d.length - 1; x > dpos; x--)
+ if (r[rpos] == d[x])
+ return (x);
+ }
+
+ // Main string matching loop. It gets executed if the characters to
+ // match are less then the characters left in the d buffer
+ int l = d.length - (rend - rpos);
+ while (l >= dpos) {
+ // Set current startpoint in d
+ int y = l;
+ // Check every character in d for equity. If the string is matched
+ // return dpos
+ for (int x = rpos; x <= rend; x++) {
+ if (x == rend)
+ return (l);
+ if (r[x] != d[y++])
+ break;
+ }
+ // Decrease l to search for the same string at next offset
+ l--;
+ }
+ // The remaining chars in d buffer were not enough or the string
+ // wasn't matched
+ return (-1);
+ }
+
+ /**
+ * Matches elements of array r from rpos to rend with array d, starting from dpos.
+ * <br>
+ * This method return true if elements of array r from rpos to rend
+ * equals elements of array d starting from dpos to dpos+(rend-rpos).
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param d The array of char that should start from a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return true if array d starts from portion of array r.
+ */
+ protected static boolean matchArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ if (d.length - dpos < rend - rpos)
+ return (false);
+ for (int i = rpos; i < rend; i++)
+ if (r[i] != d[dpos++])
+ return (false);
+ return (true);
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,203 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+
+import org.apache.cocoon.matching.AbstractRegexpMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a regular expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @author <a href="mailto:haul@apache.org">Christian Haul</a>
+ * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
+ * @version CVS $Id: CachingRegexpMatcher.java 55054 2004-10-19 08:21:39Z cziegeler $
+ */
+public class CachingRegexpMatcher extends AbstractRegexpMatcher
+ implements Configurable, Initializable, Serviceable, Disposable
+{
+
+ /** The service manager instance */
+ protected ServiceManager manager;
+
+ private String defaultParam;
+ private String defaultInput = "request-param"; // default to request parameters
+ private Configuration inputConf = null; // will become an empty configuration object
+ // during configure() so why bother here...
+ String INPUT_MODULE_ROLE = InputModule.ROLE;
+ String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+ private boolean initialized = false;
+ private InputModule input;
+ private ServiceSelector inputSelector;
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager=manager;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure(Configuration config) throws ConfigurationException {
+
+ this.defaultParam = config.getChild("parameter-name").getValue(null);
+ this.inputConf = config.getChild("input-module");
+ this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() {
+ try {
+ // obtain input module
+ this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+ if (this.defaultInput != null &&
+ this.inputSelector != null &&
+ this.inputSelector.isSelectable(this.defaultInput)
+ ){
+ this.input = (InputModule) this.inputSelector.select(this.defaultInput);
+ if (!(this.input instanceof ThreadSafe && this.inputSelector instanceof ThreadSafe) ) {
+ this.inputSelector.release(this.input);
+ this.manager.release(this.inputSelector);
+ this.input = null;
+ this.inputSelector = null;
+ }
+ this.initialized = true;
+ } else {
+ if (getLogger().isErrorEnabled())
+ getLogger().error("A problem occurred setting up '" + this.defaultInput
+ + "': Selector is "+(this.inputSelector!=null?"not ":"")
+ +"null, Component is "
+ +(this.inputSelector!=null&&this.inputSelector.isSelectable(this.defaultInput)?"known":"unknown"));
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred setting up '" + this.defaultInput + "': " + e.getMessage());
+ }
+ }
+
+
+
+ public void dispose() {
+
+ if (!this.initialized)
+ if (getLogger().isErrorEnabled())
+ getLogger().error("Uninitialized Component! FAILING");
+ else
+ if (this.inputSelector != null) {
+ if (this.input != null)
+ this.inputSelector.release(this.input);
+ this.manager.release(this.inputSelector);
+ }
+ }
+
+
+
+ protected String getMatchString(Map objectModel, Parameters parameters) {
+
+ String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+ String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+ if (!this.initialized) {
+ if (getLogger().isErrorEnabled())
+ getLogger().error("Uninitialized Component! FAILING");
+ return null;
+ }
+ if (paramName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No parameter name given. Trying to Continue");
+ }
+ if (inputName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No input module given. FAILING");
+ return null;
+ }
+
+ Object result = null;
+
+ if (this.input != null && inputName.equals(this.defaultInput)) {
+ // input module is thread safe
+ // thus we still have a reference to it
+ try {
+ if (this.input != null) {
+ result = this.input.getAttribute(paramName, this.inputConf, objectModel);
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred acquiring Parameter '" + paramName
+ + "' from '" + inputName + "': " + e.getMessage());
+ }
+ } else {
+ // input was not thread safe
+ // so acquire it again
+ ServiceSelector iputSelector = null;
+ InputModule iput = null;
+ try {
+ // obtain input module
+ iputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+ if (inputName != null && iputSelector != null && iputSelector.isSelectable(inputName)){
+ iput = (InputModule) iputSelector.select(inputName);
+ }
+ if (iput != null) {
+ result = iput.getAttribute(paramName, this.inputConf, objectModel);
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred acquiring Parameter '" + paramName
+ + "' from '" + inputName + "': " + e.getMessage());
+ } finally {
+ // release components
+ if (iputSelector != null) {
+ if (iput != null)
+ iputSelector.release(iput);
+ this.manager.release(iputSelector);
+ }
+ }
+ }
+
+ if (result instanceof String) {
+ return (String) result;
+ } else {
+ return result.toString();
+ }
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.matching.AbstractWildcardMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a wildcard expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @author <a href="mailto:haul@apache.org">Christian Haul</a>
+ * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
+ * @version CVS $Id: CachingWildcardMatcher.java 55054 2004-10-19 08:21:39Z cziegeler $
+ */
+public class CachingWildcardMatcher extends AbstractWildcardMatcher
+ implements Configurable, Initializable, Serviceable, Disposable
+{
+
+ /** The service manager instance */
+ protected ServiceManager manager;
+
+ private String defaultParam;
+ private String defaultInput = "request-param"; // default to request parameters
+ private Configuration inputConf = null; // will become an empty configuration object
+ // during configure() so why bother here...
+ String INPUT_MODULE_ROLE = InputModule.ROLE;
+ String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+ private boolean initialized = false;
+ private InputModule input;
+ private ServiceSelector inputSelector;
+
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure(Configuration config) throws ConfigurationException {
+ this.defaultParam = config.getChild("parameter-name").getValue(null);
+ this.inputConf = config.getChild("input-module");
+ this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() {
+ try {
+ // obtain input module
+ this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+ if (this.defaultInput != null &&
+ this.inputSelector != null &&
+ this.inputSelector.isSelectable(this.defaultInput)
+ ){
+ this.input = (InputModule) this.inputSelector.select(this.defaultInput);
+ if (!(this.input instanceof ThreadSafe && this.inputSelector instanceof ThreadSafe) ) {
+ this.inputSelector.release(this.input);
+ this.manager.release(this.inputSelector);
+ this.input = null;
+ this.inputSelector = null;
+ }
+ this.initialized = true;
+ } else {
+ if (getLogger().isErrorEnabled())
+ getLogger().error("A problem occurred setting up '" + this.defaultInput
+ + "': Selector is "+(this.inputSelector!=null?"not ":"")
+ +"null, Component is "
+ +(this.inputSelector!=null&&this.inputSelector.isSelectable(this.defaultInput)?"known":"unknown"));
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred setting up '" + this.defaultInput + "': " + e.getMessage());
+ }
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.activity.Disposable#dispose()
+ */
+ public void dispose() {
+ if (!this.initialized)
+ if (getLogger().isErrorEnabled())
+ getLogger().error("Uninitialized Component! FAILING");
+ else
+ if (this.inputSelector != null) {
+ if (this.input != null)
+ this.inputSelector.release(this.input);
+ this.manager.release(this.inputSelector);
+ }
+ }
+
+
+
+ protected String getMatchString(Map objectModel, Parameters parameters) {
+
+ String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+ String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+ if (!this.initialized) {
+ if (getLogger().isErrorEnabled())
+ getLogger().error("Uninitialized Component! FAILING");
+ return null;
+ }
+ if (paramName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No parameter name given. Trying to Continue");
+ }
+ if (inputName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No input module given. FAILING");
+ return null;
+ }
+
+ Object result = null;
+
+ if (this.input != null && inputName.equals(this.defaultInput)) {
+ // input module is thread safe
+ // thus we still have a reference to it
+ try {
+ if (this.input != null) {
+ result = this.input.getAttribute(paramName, this.inputConf, objectModel);
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred acquiring Parameter '" + paramName
+ + "' from '" + inputName + "': " + e.getMessage());
+ }
+ } else {
+ // input was not thread safe
+ // so acquire it again
+ ServiceSelector iputSelector = null;
+ InputModule iput = null;
+ try {
+ // obtain input module
+ iputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+ if (inputName != null && iputSelector != null && iputSelector.isSelectable(inputName)){
+ iput = (InputModule) iputSelector.select(inputName);
+ }
+ if (iput != null) {
+ result = iput.getAttribute(paramName, this.inputConf, objectModel);
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred acquiring Parameter '" + paramName
+ + "' from '" + inputName + "': " + e.getMessage());
+ } finally {
+ // release components
+ if (iputSelector != null) {
+ if (iput != null)
+ iputSelector.release(iput);
+ this.manager.release(iputSelector);
+ }
+ }
+ }
+
+ if (result instanceof String) {
+ return (String) result;
+ } else {
+ return result.toString();
+ }
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/WildcardMatcher.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/WildcardMatcher.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/WildcardMatcher.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/WildcardMatcher.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.matching.AbstractWildcardMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a wildcard expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @author <a href="mailto:haul@apache.org">Christian Haul</a>
+ * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
+ * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
+ * @version CVS $Id: WildcardMatcher.java 55054 2004-10-19 08:21:39Z cziegeler $
+ */
+public class WildcardMatcher extends AbstractWildcardMatcher
+ implements Configurable, Serviceable
+{
+
+ /** The service manager instance */
+ protected ServiceManager manager;
+
+ private String defaultParam;
+ private String defaultInput = "request-param"; // default to request parameters
+ private Configuration inputConf = null; // will become an empty configuration object
+ // during configure() so why bother here...
+ String INPUT_MODULE_ROLE = InputModule.ROLE;
+ String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager=manager;
+ }
+
+ public void configure(Configuration config) throws ConfigurationException {
+ this.defaultParam = config.getChild("parameter-name").getValue(null);
+ this.inputConf = config.getChild("input-module");
+ this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+ }
+
+ protected String getMatchString(Map objectModel, Parameters parameters) {
+
+ String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+ String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+ if (paramName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No parameter name given. Trying to continue");
+ }
+ if (inputName == null) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("No input module given. FAILING");
+ return null;
+ }
+
+ InputModule input = null;
+ ServiceSelector inputSelector = null;
+ Object result = null;
+
+ // one could test whether the input module is ThreadSafe and
+ // keep a reference for that instance. Then one would need
+ // to implement Disposable in order to release it at EOL
+ // That would probably speed up things a lot. Especially, since
+ // matchers are invoked very often.
+ // Perhaps a CachingWildcardMatcher ?
+
+ try {
+ // obtain input module
+ inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+ if (inputName != null && inputSelector != null && inputSelector.isSelectable(inputName)){
+ input = (InputModule) inputSelector.select(inputName);
+ }
+ if (input != null) {
+ result = input.getAttribute(paramName, this.inputConf, objectModel);
+ }
+ } catch (Exception e) {
+ if (getLogger().isWarnEnabled())
+ getLogger().warn("A problem occurred acquiring Parameter '" + paramName
+ + "' from '" + inputName + "': " + e.getMessage());
+ } finally {
+ // release components
+ if (inputSelector != null) {
+ if (input != null)
+ inputSelector.release(input);
+ this.manager.release(inputSelector);
+ }
+ }
+
+ if (getLogger().isDebugEnabled())
+ getLogger().debug(" using "+inputName+" obtained value "+result);
+
+ if (result instanceof String) {
+ return (String) result;
+ } else {
+ return result.toString();
+ }
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/matching/modular/WildcardMatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/AbstractReader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/AbstractReader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/AbstractReader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/AbstractReader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.SAXException;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+/**
+ * A reader can be used to generate binary output for a request. This
+ * abstract class helps in implementing a custom reader.
+ *
+ * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
+ * @version CVS $Id: AbstractReader.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public abstract class AbstractReader
+ extends AbstractLogEnabled
+ implements Reader, Recyclable {
+
+ /** The current <code>SourceResolver</code>. */
+ protected SourceResolver resolver;
+ /** The current <code>Map</code> of the object model. */
+ protected Map objectModel;
+ /** The current <code>Parameters</code>. */
+ protected Parameters parameters;
+ /** The source URI associated with the request or <b>null</b>. */
+ protected String source;
+ /** The <code>OutputStream</code> to write on. */
+ protected OutputStream out;
+
+ /**
+ * Set the <code>SourceResolver</code> the object model <code>Map</code>,
+ * the source and sitemap <code>Parameters</code> used to process the request.
+ */
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+ throws ProcessingException, SAXException, IOException {
+ this.resolver=resolver;
+ this.objectModel=objectModel;
+ this.source=src;
+ this.parameters=par;
+ }
+
+ /**
+ * Set the <code>OutputStream</code>
+ */
+ public void setOutputStream(OutputStream out) {
+ if ( out instanceof BufferedOutputStream
+ || out instanceof org.apache.cocoon.util.BufferedOutputStream ) {
+ this.out = out;
+ } else {
+ this.out = new BufferedOutputStream(out, 1536);
+ }
+ }
+
+ /**
+ * Get the mime-type of the output of this <code>Reader</code>
+ * This default implementation returns null to indicate that the
+ * mime-type specified in the sitemap is to be used
+ */
+ public String getMimeType() {
+ return null;
+ }
+
+ /**
+ * @return the time the read source was last modified or 0 if it is not
+ * possible to detect
+ */
+ public long getLastModified() {
+ return 0;
+ }
+
+ /**
+ * Recycle the component
+ */
+ public void recycle() {
+ this.out = null;
+ this.resolver = null;
+ this.source = null;
+ this.parameters = null;
+ this.objectModel = null;
+ }
+
+ /**
+ * Test if the component wants to set the content length
+ */
+ public boolean shouldSetContentLength() {
+ return false;
+ }
+
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/AbstractReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,338 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.RescaleOp;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.reading.ResourceReader;
+import org.xml.sax.SAXException;
+
+import com.sun.image.codec.jpeg.ImageFormatException;
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGDecodeParam;
+import com.sun.image.codec.jpeg.JPEGEncodeParam;
+import com.sun.image.codec.jpeg.JPEGImageDecoder;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+
+/**
+ * The <code>ImageReader</code> component is used to serve binary image data
+ * in a sitemap pipeline. It makes use of HTTP Headers to determine if
+ * the requested resource should be written to the <code>OutputStream</code>
+ * or if it can signal that it hasn't changed.
+ *
+ * Parameters:
+ * <dl>
+ * <dt><width></dt>
+ * <dd> This parameter is optional. When specified, it determines the
+ * width of the binary image.
+ * If no height parameter is specified, the aspect ratio
+ * of the image is kept. The parameter may be expressed as an int or a percentage.
+ * </dd>
+ * <dt><height></dt>
+ * <dd> This parameter is optional. When specified, it determines the
+ * height of the binary image.
+ * If no width parameter is specified, the aspect ratio
+ * of the image is kept. The parameter may be expressed as an int or a percentage.
+ * </dd>
+ * <dt><scale(Red|Green|Blue)></dt>
+ * <dd>This parameter is optional. When specified it will cause the
+ * specified color component in the image to be multiplied by the
+ * specified floating point value.
+ * </dd>
+ * <dt><offset(Red|Green|Blue)></dt>
+ * <dd>This parameter is optional. When specified it will cause the
+ * specified color component in the image to be incremented by the
+ * specified floating point value.
+ * </dd>
+ * <dt><grayscale></dt>
+ * <dd>This parameter is optional. When specified and set to true it
+ * will cause each image pixel to be normalized. Default is "false".
+ * </dd>
+ * <dt><allow-enlarging></dt>
+ * <dd>This parameter is optional. By default, if the image is smaller
+ * than the specified width and height, the image will be enlarged.
+ * In some circumstances this behaviour is undesirable, and can be
+ * switched off by setting this parameter to "<code>false</code>" so that
+ * images will be reduced in size, but not enlarged. The default is
+ * "<code>true</code>".
+ * </dd>
+ * <dt><quality></dt>
+ * <dd>This parameter is optional. By default, the quality uses the
+ * default for the JVM. If it is specified, the proper JPEG quality
+ * compression is used. The range is 0.0 to 1.0, if specified.
+ * </dd>
+ * </dl>
+ *
+ * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
+ * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
+ * @author <a href="mailto:tcurdt@apache.org">Torsten Curdt</a>
+ * @author <a href="mailto:eric@plauditdesign.com">Eric Caron</a>
+ * @version CVS $Id: ImageReader.java 289507 2005-09-16 12:07:41Z jheymans $
+ */
+final public class ImageReader extends ResourceReader {
+ private static final boolean GRAYSCALE_DEFAULT = false;
+ private static final boolean ENLARGE_DEFAULT = true;
+ private static final boolean FIT_DEFAULT = false;
+
+ private int width;
+ private int height;
+ private float[] scaleColor = new float[3];
+ private float[] offsetColor = new float[3];
+ private float[] quality = new float[1];
+
+ private boolean enlarge;
+ private boolean fitUniform;
+ private boolean usePercent;
+ private RescaleOp colorFilter;
+ private ColorConvertOp grayscaleFilter;
+
+
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+ throws ProcessingException, SAXException, IOException {
+
+ char lastChar;
+ String tmpWidth = par.getParameter("width", "0");
+ String tmpHeight = par.getParameter("height", "0");
+
+ this.scaleColor[0] = par.getParameterAsFloat("scaleRed", -1.0f);
+ this.scaleColor[1] = par.getParameterAsFloat("scaleGreen", -1.0f);
+ this.scaleColor[2] = par.getParameterAsFloat("scaleBlue", -1.0f);
+ this.offsetColor[0] = par.getParameterAsFloat("offsetRed", 0.0f);
+ this.offsetColor[1] = par.getParameterAsFloat("offsetGreen", 0.0f);
+ this.offsetColor[2] = par.getParameterAsFloat("offsetBlue", 0.0f);
+ this.quality[0] = par.getParameterAsFloat("quality", 0.9f);
+
+ boolean filterColor = false;
+ for (int i = 0; i < 3; ++i) {
+ if (this.scaleColor[i] != -1.0f) {
+ filterColor = true;
+ } else {
+ this.scaleColor[i] = 1.0f;
+ }
+ if (this.offsetColor[i] != 0.0f) {
+ filterColor = true;
+ }
+ }
+
+ if (filterColor) {
+ this.colorFilter = new RescaleOp(scaleColor, offsetColor, null);
+ }
+
+ usePercent = false;
+ lastChar = tmpWidth.charAt(tmpWidth.length() - 1);
+ if (lastChar == '%') {
+ usePercent = true;
+ width = Integer.parseInt(tmpWidth.substring(0, tmpWidth.length() - 1));
+ } else {
+ width = Integer.parseInt(tmpWidth);
+ }
+
+ lastChar = tmpHeight.charAt(tmpHeight.length() - 1);
+ if(lastChar == '%') {
+ usePercent = true;
+ height = Integer.parseInt(tmpHeight.substring(0, tmpHeight.length() - 1));
+ } else {
+ height = Integer.parseInt(tmpHeight);
+ }
+
+ if (par.getParameterAsBoolean("grayscale", GRAYSCALE_DEFAULT)) {
+ this.grayscaleFilter = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
+ }
+
+ this.enlarge = par.getParameterAsBoolean("allow-enlarging", ENLARGE_DEFAULT);
+ this.fitUniform = par.getParameterAsBoolean("fit-uniform", FIT_DEFAULT);
+
+ super.setup(resolver, objectModel, src, par);
+ }
+
+ protected void setupHeaders() {
+ // Reset byte ranges support for dynamic response
+ if (byteRanges && hasTransform()) {
+ byteRanges = false;
+ }
+
+ super.setupHeaders();
+ }
+
+ /**
+ * @return True if image transform is specified
+ */
+ private boolean hasTransform() {
+ return width > 0 || height > 0 || null != colorFilter || null != grayscaleFilter || (this.quality[0] != 0.9f);
+ }
+
+ /**
+ * Returns the affine transform that implements the scaling.
+ * The behavior is the following: if both the new width and height values
+ * are positive, the image is rescaled according to these new values and
+ * the original aspect ratio is lost.
+ * Otherwise, if one of the two parameters is zero or negative, the
+ * aspect ratio is maintained and the positive parameter indicates the
+ * scaling.
+ * If both new values are zero or negative, no scaling takes place (a unit
+ * transformation is applied).
+ */
+ private AffineTransform getTransform(double ow, double oh, double nw, double nh) {
+ double wm = 1.0d;
+ double hm = 1.0d;
+
+ if (fitUniform) {
+ //
+ // Compare aspect ratio of image vs. that of the "box"
+ // defined by nw and nh
+ //
+ if (ow/oh > nw/nh) {
+ nh = 0; // Original image is proportionately wider than the box,
+ // so scale to fit width
+ } else {
+ nw = 0; // Scale to fit height
+ }
+ }
+
+ if (nw > 0) {
+ wm = nw / ow;
+ if (nh > 0) {
+ hm = nh / oh;
+ } else {
+ hm = wm;
+ }
+ } else {
+ if (nh > 0) {
+ hm = nh / oh;
+ wm = hm;
+ }
+ }
+
+ if (!enlarge) {
+ if ((nw > ow && nh <= 0) || (nh > oh && nw <=0)) {
+ wm = 1.0d;
+ hm = 1.0d;
+ } else if (nw > ow) {
+ wm = 1.0d;
+ } else if (nh > oh) {
+ hm = 1.0d;
+ }
+ }
+ return new AffineTransform(wm, 0.0d, 0.0d, hm, 0.0d, 0.0d);
+ }
+
+ protected void processStream(InputStream inputStream) throws IOException, ProcessingException {
+ if (hasTransform()) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("image " + ((width == 0) ? "?" : Integer.toString(width))
+ + "x" + ((height == 0) ? "?" : Integer.toString(height))
+ + " expires: " + expires);
+ }
+
+ try {
+ JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inputStream);
+ BufferedImage original = decoder.decodeAsBufferedImage();
+ BufferedImage currentImage = original;
+
+ if (width > 0 || height > 0) {
+ JPEGDecodeParam decodeParam = decoder.getJPEGDecodeParam();
+ double ow = decodeParam.getWidth();
+ double oh = decodeParam.getHeight();
+
+ if (usePercent == true) {
+ if (width > 0) {
+ width = Math.round((int)(ow * width) / 100);
+ }
+ if (height > 0) {
+ height = Math.round((int)(oh * height) / 100);
+ }
+ }
+
+ AffineTransformOp filter = new AffineTransformOp(getTransform(ow, oh, width, height), AffineTransformOp.TYPE_BILINEAR);
+ WritableRaster scaledRaster = filter.createCompatibleDestRaster(currentImage.getRaster());
+
+ filter.filter(currentImage.getRaster(), scaledRaster);
+
+ currentImage = new BufferedImage(original.getColorModel(), scaledRaster, true, null);
+ }
+
+ if (null != grayscaleFilter) {
+ grayscaleFilter.filter(currentImage, currentImage);
+ }
+
+ if (null != colorFilter) {
+ colorFilter.filter(currentImage, currentImage);
+ }
+ JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
+ JPEGEncodeParam p = encoder.getDefaultJPEGEncodeParam(currentImage);
+ p.setQuality(this.quality[0], true);
+ encoder.setJPEGEncodeParam(p);
+ encoder.encode(currentImage);
+ out.flush();
+ } catch (ImageFormatException e) {
+ throw new ProcessingException("Error reading the image. " +
+ "Note that only JPEG images are currently supported.");
+ } finally {
+ // Bugzilla Bug 25069, close inputStream in finally block
+ // this will close inputStream even if processStream throws
+ // an exception
+ inputStream.close();
+ }
+ } else {
+ // only read the resource - no modifications requested
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("passing original resource");
+ }
+ super.processStream(inputStream);
+ }
+ }
+
+ /**
+ * Generate the unique key.
+ * This key must be unique inside the space of this component.
+ *
+ * @return The generated key consists of the src and width and height, and the color transform
+ * parameters
+ */
+ public Serializable getKey() {
+ return this.inputSource.getURI()
+ + ':' + this.width
+ + ':' + this.height
+ + ":" + this.scaleColor[0]
+ + ":" + this.scaleColor[1]
+ + ":" + this.scaleColor[2]
+ + ":" + this.offsetColor[0]
+ + ":" + this.offsetColor[1]
+ + ":" + this.offsetColor[2]
+ + ":" + this.quality[0]
+ + ":" + ((null == this.grayscaleFilter) ? "color" : "grayscale")
+ + ":" + super.getKey();
+ }
+
+ public void recycle(){
+ super.recycle();
+ this.colorFilter = null;
+ this.grayscaleFilter = null;
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ImageReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/Reader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/Reader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/Reader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/Reader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.sitemap.SitemapOutputComponent;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+/**
+ * A reader can be used to generate binary output for a request.
+ *
+ * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
+ * @version CVS $Id: Reader.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public interface Reader extends SitemapModelComponent, SitemapOutputComponent {
+
+ String ROLE = Reader.class.getName();
+
+ /**
+ * Generate the response.
+ */
+ void generate()
+ throws IOException, SAXException, ProcessingException;
+
+ /**
+ * @return the time the read source was last modified or 0 if it is not
+ * possible to detect
+ */
+ long getLastModified();
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/Reader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ResourceReader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ResourceReader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ResourceReader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ResourceReader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,363 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.http.HttpResponse;
+import org.apache.cocoon.util.ByteRange;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The <code>ResourceReader</code> component is used to serve binary data
+ * in a sitemap pipeline. It makes use of HTTP Headers to determine if
+ * the requested resource should be written to the <code>OutputStream</code>
+ * or if it can signal that it hasn't changed.
+ *
+ * <p>Configuration:
+ * <dl>
+ * <dt><expires></dt>
+ * <dd>This parameter is optional. When specified it determines how long
+ * in miliseconds the resources can be cached by any proxy or browser
+ * between Cocoon and the requesting visitor. Defaults to -1.
+ * </dd>
+ * <dt><quick-modified-test></dt>
+ * <dd>This parameter is optional. This boolean parameter controls the
+ * last modified test. If set to true (default is false), only the
+ * last modified of the current source is tested, but not if the
+ * same source is used as last time
+ * (see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102921894301915 )
+ * </dd>
+ * <dt><byte-ranges></dt>
+ * <dd>This parameter is optional. This boolean parameter controls whether
+ * Cocoon should support byterange requests (to allow clients to resume
+ * broken/interrupted downloads).
+ * Defaults to true.
+ * </dl>
+ *
+ * <p>Default configuration:
+ * <pre>
+ * <expires>-1</expires>
+ * <quick-modified-test>false</quick-modified-test>
+ * <byte-ranges>true</byte-ranges>
+ * </pre>
+ *
+ * <p>In addition to reader configuration, above parameters can be passed
+ * to the reader at the time when it is used.
+ *
+ * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
+ * @author <a href="mailto:tcurdt@apache.org">Torsten Curdt</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: ResourceReader.java 155099 2005-02-23 22:48:09Z vgritsenko $
+ */
+public class ResourceReader extends AbstractReader
+ implements CacheableProcessingComponent, Configurable {
+
+ /**
+ * The list of generated documents
+ */
+ private static final Map documents = new HashMap();
+
+ protected long configuredExpires;
+ protected boolean configuredQuickTest;
+ protected int configuredBufferSize;
+ protected boolean configuredByteRanges;
+
+ protected long expires;
+ protected boolean quickTest;
+ protected int bufferSize;
+ protected boolean byteRanges;
+
+ protected Response response;
+ protected Request request;
+ protected Source inputSource;
+
+ /**
+ * Read reader configuration
+ */
+ public void configure(Configuration configuration) throws ConfigurationException {
+ // VG Parameters are deprecated as of 2.2.0-Dev/2.1.6-Dev
+ final Parameters parameters = Parameters.fromConfiguration(configuration);
+ this.configuredExpires = parameters.getParameterAsLong("expires", -1);
+ this.configuredQuickTest = parameters.getParameterAsBoolean("quick-modified-test", false);
+ this.configuredBufferSize = parameters.getParameterAsInteger("buffer-size", 8192);
+ this.configuredByteRanges = parameters.getParameterAsBoolean("byte-ranges", true);
+
+ // Configuration has precedence over parameters.
+ this.configuredExpires = configuration.getChild("expires").getValueAsLong(configuredExpires);
+ this.configuredQuickTest = configuration.getChild("quick-modified-test").getValueAsBoolean(configuredQuickTest);
+ this.configuredBufferSize = configuration.getChild("buffer-size").getValueAsInteger(configuredBufferSize);
+ this.configuredByteRanges = configuration.getChild("byte-ranges").getValueAsBoolean(configuredByteRanges);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(Parameters)
+ */
+ public void parameterize(Parameters parameters) throws ParameterException {
+ }
+
+ /**
+ * Setup the reader.
+ * The resource is opened to get an <code>InputStream</code>,
+ * the length and the last modification date
+ */
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+ throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, src, par);
+
+ this.request = ObjectModelHelper.getRequest(objectModel);
+ this.response = ObjectModelHelper.getResponse(objectModel);
+
+ this.expires = par.getParameterAsLong("expires", this.configuredExpires);
+ this.quickTest = par.getParameterAsBoolean("quick-modified-test", this.configuredQuickTest);
+ this.bufferSize = par.getParameterAsInteger("buffer-size", this.configuredBufferSize);
+ this.byteRanges = par.getParameterAsBoolean("byte-ranges", this.configuredByteRanges);
+
+ try {
+ this.inputSource = resolver.resolveURI(src);
+ } catch (SourceException e) {
+ throw SourceUtil.handle("Error during resolving of '" + src + "'.", e);
+ }
+
+ setupHeaders();
+ }
+
+ /**
+ * Setup the response headers: Accept-Ranges, Expires.
+ */
+ protected void setupHeaders() {
+ // Tell the client whether we support byte range requests or not
+ if (byteRanges) {
+ response.setHeader("Accept-Ranges", "bytes");
+ } else {
+ response.setHeader("Accept-Ranges", "none");
+ }
+
+ if (expires > 0) {
+ response.setDateHeader("Expires", System.currentTimeMillis() + expires);
+ } else if (expires == 0) {
+ // See Bug #14048
+ response.addHeader("Vary", "Host");
+ }
+ }
+
+ /**
+ * Recyclable
+ */
+ public void recycle() {
+ this.request = null;
+ this.response = null;
+ if (this.inputSource != null) {
+ super.resolver.release(this.inputSource);
+ this.inputSource = null;
+ }
+ super.recycle();
+ }
+
+ /**
+ * @return True if byte ranges support is enabled and request has range header.
+ */
+ protected boolean hasRanges() {
+ return this.byteRanges && this.request.getHeader("Range") != null;
+ }
+
+ /**
+ * Generate the unique key.
+ * This key must be unique inside the space of this component.
+ *
+ * @return The generated key hashes the src
+ */
+ public Serializable getKey() {
+ return inputSource.getURI();
+ }
+
+ /**
+ * Generate the validity object.
+ *
+ * @return The generated validity object or <code>null</code> if the
+ * component is currently not cacheable.
+ */
+ public SourceValidity getValidity() {
+ if (hasRanges()) {
+ // This is a byte range request so we can't use the cache, return null.
+ return null;
+ } else {
+ return inputSource.getValidity();
+ }
+ }
+
+ /**
+ * @return the time the read source was last modified or 0 if it is not
+ * possible to detect
+ */
+ public long getLastModified() {
+ if (hasRanges()) {
+ // This is a byte range request so we can't use the cache, return null.
+ return 0;
+ }
+
+ if (quickTest) {
+ return inputSource.getLastModified();
+ }
+
+ final String systemId = (String) documents.get(request.getRequestURI());
+ if (systemId == null || inputSource.getURI().equals(systemId)) {
+ return inputSource.getLastModified();
+ }
+
+ documents.remove(request.getRequestURI());
+ return 0;
+ }
+
+ protected void processStream(InputStream inputStream)
+ throws IOException, ProcessingException {
+ byte[] buffer = new byte[bufferSize];
+ int length = -1;
+
+ String ranges = request.getHeader("Range");
+
+ ByteRange byteRange;
+ if (byteRanges && ranges != null) {
+ try {
+ ranges = ranges.substring(ranges.indexOf('=') + 1);
+ byteRange = new ByteRange(ranges);
+ } catch (NumberFormatException e) {
+ byteRange = null;
+
+ // TC: Hm.. why don't we have setStatus in the Response interface ?
+ if (response instanceof HttpResponse) {
+ // Respond with status 416 (Request range not satisfiable)
+ ((HttpResponse)response).setStatus(416);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("malformed byte range header [" + String.valueOf(ranges) + "]");
+ }
+ }
+ }
+ } else {
+ byteRange = null;
+ }
+
+ long contentLength = inputSource.getContentLength();
+
+ if (byteRange != null) {
+ String entityLength;
+ String entityRange;
+ if (contentLength != -1) {
+ entityLength = "" + contentLength;
+ entityRange = byteRange.intersection(new ByteRange(0, contentLength)).toString();
+ } else {
+ entityLength = "*";
+ entityRange = byteRange.toString();
+ }
+
+ response.setHeader("Content-Range", entityRange + "/" + entityLength);
+ if (response instanceof HttpResponse) {
+ // Response with status 206 (Partial content)
+ ((HttpResponse)response).setStatus(206);
+ }
+
+ int pos = 0;
+ int posEnd;
+ while ((length = inputStream.read(buffer)) > -1) {
+ posEnd = pos + length - 1;
+ ByteRange intersection = byteRange.intersection(new ByteRange(pos, posEnd));
+ if (intersection != null) {
+ out.write(buffer, (int) intersection.getStart() - pos, (int) intersection.length());
+ }
+ pos += length;
+ }
+ } else {
+ if (contentLength != -1) {
+ response.setHeader("Content-Length", Long.toString(contentLength));
+ }
+
+ while ((length = inputStream.read(buffer)) > -1) {
+ out.write(buffer, 0, length);
+ }
+ }
+
+ out.flush();
+ }
+
+ /**
+ * Generates the requested resource.
+ */
+ public void generate()
+ throws IOException, ProcessingException {
+ try {
+ InputStream inputStream;
+ try {
+ inputStream = inputSource.getInputStream();
+ } catch (SourceException e) {
+ throw SourceUtil.handle("Error during resolving of the input stream", e);
+ }
+
+ // Bugzilla Bug #25069: Close inputStream in finally block.
+ try {
+ processStream(inputStream);
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+
+ if (!quickTest) {
+ // if everything is ok, add this to the list of generated documents
+ // (see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102921894301915 )
+ documents.put(request.getRequestURI(), inputSource.getURI());
+ }
+ } catch (IOException e) {
+ getLogger().debug("Received an IOException, assuming client severed connection on purpose");
+ }
+ }
+
+ /**
+ * Returns the mime-type of the resource in process.
+ */
+ public String getMimeType() {
+ Context ctx = ObjectModelHelper.getContext(objectModel);
+ if (ctx != null) {
+ final String mimeType = ctx.getMimeType(source);
+ if (mimeType != null) {
+ return mimeType;
+ }
+ }
+
+ return inputSource.getMimeType();
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ResourceReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ServiceableReader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ServiceableReader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ServiceableReader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ServiceableReader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * The serviceable reader will allow any {@link Reader} implementation that
+ * extends this to access other Avalon components.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ *
+ * @version CVS $Id: ServiceableReader.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public abstract class ServiceableReader
+ extends AbstractReader
+ implements Serviceable {
+
+
+ protected ServiceManager manager;
+
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service(ServiceManager manager)
+ throws ServiceException {
+ this.manager = manager;
+ }
+
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/ServiceableReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/VirtualPipelineReader.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/VirtualPipelineReader.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/VirtualPipelineReader.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/VirtualPipelineReader.java Thu Nov 3 05:41:06 2005
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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.apache.cocoon.reading;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.impl.AbstractVirtualSitemapComponent;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class VirtualPipelineReader extends AbstractVirtualSitemapComponent
+ implements Reader {
+
+ protected String getTypeName() {
+ return "reader";
+ }
+
+ /**
+ * Set the <code>OutputStream</code>
+ */
+ public void setOutputStream(OutputStream out) {
+ this.getMappedSourceEnvironment().setOutputStream(out);
+ }
+
+ /**
+ * Get the mime-type of the output of this <code>Reader</code>
+ */
+ public String getMimeType() {
+ return this.getPipeline().getMimeType();
+ }
+
+ /**
+ * @return the time the read source was last modified or 0 if it is not
+ * possible to detect
+ */
+ public long getLastModified() {
+ return 0;
+ }
+
+ /**
+ * Test if the component wants to set the content length
+ */
+ public boolean shouldSetContentLength() {
+ return this.getPipeline().shouldSetContentLength();
+ }
+
+ public void generate()
+ throws IOException, SAXException, ProcessingException {
+
+ // Should use SourceResolver and context of the this
+ // components' sitemap, not caller sitemap
+ EnvironmentHelper.enterEnvironment(this.getVPCEnvironment());
+ try {
+ this.getPipeline().prepareInternal(this.getVPCEnvironment());
+ } finally {
+ EnvironmentHelper.leaveEnvironment();
+ }
+
+ // Should use SourceResolver of the this components' sitemap, not caller sitemap
+ EnvironmentHelper.enterEnvironment(this.getMappedSourceEnvironment());
+ try {
+ this.getPipeline().process(this.getMappedSourceEnvironment());
+ } finally {
+ EnvironmentHelper.leaveEnvironment();
+ }
+ }
+}
Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/reading/VirtualPipelineReader.java
------------------------------------------------------------------------------
svn:eol-style = native