/*
* 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);
}
}