/* * This file is part of "SnipSnap Radeox Rendering Engine". * * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel * All Rights Reserved. * * Please visit http://radeox.org/ for updates and contact. * * --LICENSE NOTICE-- * 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. * --LICENSE NOTICE-- */ package org.radeox.filter; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.radeox.api.engine.context.InitialRenderContext; import org.radeox.api.engine.context.RenderContext; import org.radeox.engine.context.BaseInitialRenderContext; import org.radeox.filter.context.FilterContext; /* * FilterPipe is a collection of Filters which are applied one by one to an * input to generate output @author stephan @team sonicteam * * @version $Id: FilterPipe.java 7756 2006-04-13 12:25:49Z ian@caret.cam.ac.uk $ */ public class FilterPipe { private static Log log = LogFactory.getLog(FilterPipe.class); public final static String FIRST_IN_PIPE = "all"; public final static String LAST_IN_PIPE = "none"; public final static String[] EMPTY_BEFORE = new String[] {}; public final static String[] NO_REPLACES = new String[] {}; public final static String[] FIRST_BEFORE = new String[] { FIRST_IN_PIPE }; private InitialRenderContext initialContext; private List filterList = null; private static Object[] noArguments = new Object[] {}; public FilterPipe() { this(new BaseInitialRenderContext()); } public FilterPipe(InitialRenderContext context) { filterList = new ArrayList(); initialContext = context; } public void init() { Iterator iterator = new ArrayList(filterList).iterator(); while (iterator.hasNext()) { Filter filter = (Filter) iterator.next(); String[] replaces = filter.replaces(); for (int i = 0; i < replaces.length; i++) { String replace = replaces[i]; removeFilter(replace); } } } public void removeFilter(String filterClass) { Iterator iterator = filterList.iterator(); while (iterator.hasNext()) { Filter filter = (Filter) iterator.next(); if (filter.getClass().getName().equals(filterClass)) { iterator.remove(); } } } /** * Add a filter to the pipe * * @param filter * Filter to add */ public void addFilter(Filter filter) { filter.setInitialContext(initialContext); int minIndex = Integer.MAX_VALUE; String[] before = filter.before(); for (int i = 0; i < before.length; i++) { String s = before[i]; int index = index(filterList, s); if (index < minIndex) { minIndex = index; } } if (minIndex == Integer.MAX_VALUE) { // -1 is more usable for not-found than MAX_VALUE minIndex = -1; } if (contains(filter.before(), FIRST_IN_PIPE)) { filterList.add(0, filter); } else if (minIndex != -1) { filterList.add(minIndex, filter); // } else if (contains(filter.before(), LAST_IN_PIPE)) { // filterList.add(-1, filter); } else { filterList.add(filter); } } public int index(String filterName) { return FilterPipe.index(filterList, filterName); } public static int index(List list, final String filterName) { for (int i = 0; i < list.size(); i++) { if (filterName.equals(list.get(i).getClass().getName())) return i; } return -1; } public static boolean contains(Object[] array, Object value) { return (Arrays.binarySearch(array, value) != -1); } /** * Filter some input and generate ouput. FilterPipe pipes the string input * through every filter in the pipe and returns the resulting string. * * @param input * Input string which should be transformed * @param context * FilterContext with information about the enviroment * @return result Filtered output */ public String filter(String input, FilterContext context) { // Logger.debug("FilterPipe.filter: context = "+context); String output = input; Iterator filterIterator = filterList.iterator(); RenderContext renderContext = context.getRenderContext(); // Apply every filter in filterList to input string while (filterIterator.hasNext()) { Filter f = (Filter) filterIterator.next(); try { // assume all filters non cacheable if (f instanceof CacheFilter) { renderContext.setCacheable(true); } else { renderContext.setCacheable(false); } String tmp = f.filter(output, context); if (output.equals(tmp)) { renderContext.setCacheable(true); } if (null == tmp) { log.warn("FilterPipe.filter: error while filtering: " + f); } else { output = tmp; } renderContext.commitCache(); } catch (Exception e) { log.warn("Filtering exception: " + f, e); } } return output; } public Filter getFilter(int index) { return (Filter) filterList.get(index); } }