001: /*
002: * This file is part of "SnipSnap Radeox Rendering Engine".
003: *
004: * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel
005: * All Rights Reserved.
006: *
007: * Please visit http://radeox.org/ for updates and contact.
008: *
009: * --LICENSE NOTICE--
010: * Licensed under the Apache License, Version 2.0 (the "License");
011: * you may not use this file except in compliance with the License.
012: * You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: * --LICENSE NOTICE--
022: */
023:
024: package org.radeox.filter;
025:
026: import java.util.ArrayList;
027: import java.util.Arrays;
028: import java.util.Iterator;
029: import java.util.List;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.radeox.api.engine.context.InitialRenderContext;
034: import org.radeox.api.engine.context.RenderContext;
035: import org.radeox.engine.context.BaseInitialRenderContext;
036: import org.radeox.filter.context.FilterContext;
037:
038: /*
039: * FilterPipe is a collection of Filters which are applied one by one to an
040: * input to generate output @author stephan @team sonicteam
041: *
042: * @version $Id: FilterPipe.java 7756 2006-04-13 12:25:49Z ian@caret.cam.ac.uk $
043: */
044:
045: public class FilterPipe {
046: private static Log log = LogFactory.getLog(FilterPipe.class);
047:
048: public final static String FIRST_IN_PIPE = "all";
049:
050: public final static String LAST_IN_PIPE = "none";
051:
052: public final static String[] EMPTY_BEFORE = new String[] {};
053:
054: public final static String[] NO_REPLACES = new String[] {};
055:
056: public final static String[] FIRST_BEFORE = new String[] { FIRST_IN_PIPE };
057:
058: private InitialRenderContext initialContext;
059:
060: private List filterList = null;
061:
062: private static Object[] noArguments = new Object[] {};
063:
064: public FilterPipe() {
065: this (new BaseInitialRenderContext());
066: }
067:
068: public FilterPipe(InitialRenderContext context) {
069: filterList = new ArrayList();
070: initialContext = context;
071: }
072:
073: public void init() {
074: Iterator iterator = new ArrayList(filterList).iterator();
075: while (iterator.hasNext()) {
076: Filter filter = (Filter) iterator.next();
077: String[] replaces = filter.replaces();
078: for (int i = 0; i < replaces.length; i++) {
079: String replace = replaces[i];
080: removeFilter(replace);
081: }
082: }
083: }
084:
085: public void removeFilter(String filterClass) {
086: Iterator iterator = filterList.iterator();
087: while (iterator.hasNext()) {
088: Filter filter = (Filter) iterator.next();
089: if (filter.getClass().getName().equals(filterClass)) {
090: iterator.remove();
091: }
092: }
093: }
094:
095: /**
096: * Add a filter to the pipe
097: *
098: * @param filter
099: * Filter to add
100: */
101: public void addFilter(Filter filter) {
102: filter.setInitialContext(initialContext);
103:
104: int minIndex = Integer.MAX_VALUE;
105: String[] before = filter.before();
106: for (int i = 0; i < before.length; i++) {
107: String s = before[i];
108: int index = index(filterList, s);
109: if (index < minIndex) {
110: minIndex = index;
111: }
112: }
113: if (minIndex == Integer.MAX_VALUE) {
114: // -1 is more usable for not-found than MAX_VALUE
115: minIndex = -1;
116: }
117:
118: if (contains(filter.before(), FIRST_IN_PIPE)) {
119: filterList.add(0, filter);
120: } else if (minIndex != -1) {
121: filterList.add(minIndex, filter);
122: // } else if (contains(filter.before(), LAST_IN_PIPE)) {
123: // filterList.add(-1, filter);
124: } else {
125: filterList.add(filter);
126: }
127: }
128:
129: public int index(String filterName) {
130: return FilterPipe.index(filterList, filterName);
131: }
132:
133: public static int index(List list, final String filterName) {
134: for (int i = 0; i < list.size(); i++) {
135: if (filterName.equals(list.get(i).getClass().getName()))
136: return i;
137: }
138: return -1;
139: }
140:
141: public static boolean contains(Object[] array, Object value) {
142: return (Arrays.binarySearch(array, value) != -1);
143: }
144:
145: /**
146: * Filter some input and generate ouput. FilterPipe pipes the string input
147: * through every filter in the pipe and returns the resulting string.
148: *
149: * @param input
150: * Input string which should be transformed
151: * @param context
152: * FilterContext with information about the enviroment
153: * @return result Filtered output
154: */
155: public String filter(String input, FilterContext context) {
156: // Logger.debug("FilterPipe.filter: context = "+context);
157: String output = input;
158: Iterator filterIterator = filterList.iterator();
159: RenderContext renderContext = context.getRenderContext();
160:
161: // Apply every filter in filterList to input string
162: while (filterIterator.hasNext()) {
163: Filter f = (Filter) filterIterator.next();
164: try {
165: // assume all filters non cacheable
166: if (f instanceof CacheFilter) {
167: renderContext.setCacheable(true);
168: } else {
169: renderContext.setCacheable(false);
170: }
171: String tmp = f.filter(output, context);
172: if (output.equals(tmp)) {
173: renderContext.setCacheable(true);
174: }
175: if (null == tmp) {
176: log
177: .warn("FilterPipe.filter: error while filtering: "
178: + f);
179: } else {
180: output = tmp;
181: }
182: renderContext.commitCache();
183: } catch (Exception e) {
184: log.warn("Filtering exception: " + f, e);
185: }
186: }
187: return output;
188: }
189:
190: public Filter getFilter(int index) {
191: return (Filter) filterList.get(index);
192: }
193: }
|