/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: AbstractFlowTagsProcessor.java 3917 2008-04-14 16:55:14Z gbevin $
*/
package com.uwyn.rife.engine;
import com.uwyn.rife.engine.exceptions.EngineTemplateProcessingException;
import com.uwyn.rife.engine.exceptions.ExpectedStringConstantFieldException;
import com.uwyn.rife.template.Template;
import com.uwyn.rife.template.TemplateEncoder;
import java.util.*;
abstract class AbstractFlowTagsProcessor<FlowTagsProcessorType extends AbstractFlowTagsProcessor, Entity>
{
private final ElementContext mContext;
private final Map<String, String[]> mOutputValueMap;
private final Template mTemplate;
private final TemplateEncoder mEncoder;
private String mFocusedName;
private boolean mProcessQueryTags;
private boolean mProcessFormTags;
private boolean mReplaceExistingValues;
private List<String> mSetValues;
private Map<String, String> mFormUrls;
private Map<String, String> mFormParams;
AbstractFlowTagsProcessor(final ElementContext context, final Map<String, String[]> outputValueMap, final Template template)
{
mContext = context;
mOutputValueMap = outputValueMap;
mTemplate = template;
mEncoder = template.getEncoder();
reset();
}
synchronized List<String> processTags()
{
mSetValues = new ArrayList<String>();
mFormUrls = null;
mFormParams = null;
if (mFocusedName != null)
{
processNameTag(mFocusedName);
}
else
{
processNamedTags();
}
processFieldTags();
ensurePresenceOfRequiredMatchingTags();
return mSetValues;
}
ElementContext getContext()
{
return mContext;
}
Map<String, String[]> getOutputValueMap()
{
return mOutputValueMap;
}
synchronized FlowTagsProcessorType reset()
{
mFocusedName = null;
mProcessFormTags = true;
mProcessQueryTags = true;
mReplaceExistingValues = false;
return (FlowTagsProcessorType)this;
}
synchronized FlowTagsProcessorType focusOnName(final String name)
{
mFocusedName = name;
return (FlowTagsProcessorType)this;
}
synchronized FlowTagsProcessorType onlyProcessFormTags()
{
mProcessQueryTags = false;
return (FlowTagsProcessorType)this;
}
synchronized FlowTagsProcessorType onlyProcessQueryTags()
{
mProcessFormTags = false;
return (FlowTagsProcessorType)this;
}
synchronized FlowTagsProcessorType replaceExistingValues()
{
mReplaceExistingValues = true;
return (FlowTagsProcessorType)this;
}
protected abstract String getEntityName();
protected abstract String getQueryPrefix();
protected abstract String getFormPrefix();
protected abstract String getParamsPrefix();
protected abstract String getParamsjsPrefix();
protected abstract String getFieldTag();
protected abstract Collection<String> getNames();
protected abstract Entity getEntity(String name);
protected abstract CharSequenceDeferred generateEntityQueryUrl(Entity entity);
protected abstract CharSequenceDeferred generateEntityFormUrl(Entity entity);
protected abstract CharSequenceDeferred generateEntityFormParameters(Entity entity);
protected abstract CharSequenceDeferred generateEntityFormParametersJavascript(Entity entity);
private void processNamedTags()
{
Collection<String> names = getNames();
if (names.size() > 0)
{
for (String name : names)
{
processNameTag(name);
}
}
}
private void processNameTag(final String name)
{
final Entity entity = getEntity(name);
if (entity != null)
{
final String query_value_id = getQueryPrefix() + name;
final String form_value_id = getFormPrefix() + name;
final String params_value_id = getParamsPrefix() + name;
final String paramsjs_value_id = getParamsjsPrefix() + name;
if (mProcessQueryTags && mTemplate.hasValueId(query_value_id))
{
generateQueryUrl(entity, query_value_id);
}
if (mProcessFormTags)
{
if (mTemplate.hasValueId(form_value_id))
{
generateFormUrl(name, entity, form_value_id);
}
if (mTemplate.hasValueId(params_value_id))
{
generateFormParameters(name, entity, params_value_id);
}
if (mTemplate.hasValueId(paramsjs_value_id))
{
generateFormParametersJavascript(name, entity, paramsjs_value_id);
}
}
}
}
private void processFieldTags()
{
if (mTemplate.hasFilteredValues(getFieldTag()))
{
final List<String[]> fields_filtered = mTemplate.getFilteredValues(getFieldTag());
for (final String[] field_tag_matches : fields_filtered)
{
// obtain the name by retrieving the string value for
// the field that is specified in the tag
final String tag = field_tag_matches[0];
final String tag_suffix = field_tag_matches[1];
final String field_name = field_tag_matches[2];
try
{
String name = EngineTemplateHelper.getFlowEntityNameFromFieldTag(mContext.getElementSupport(), tag, field_name);
if (name != null &&
(null == mFocusedName || name.equals(mFocusedName)))
{
final Entity entity = getEntity(name);
if (entity != null)
{
if (mProcessQueryTags)
{
if (ElementContext.SUFFIX_QUERY.equals(tag_suffix))
{
generateQueryUrl(entity, tag);
}
}
if (mProcessFormTags)
{
if (ElementContext.SUFFIX_FORM.equals(tag_suffix))
{
generateFormUrl(name, entity, tag);
}
else if (ElementContext.SUFFIX_PARAMS.equals(tag_suffix))
{
generateFormParameters(name, entity, tag);
}
else if (ElementContext.SUFFIX_PARAMSJS.equals(tag_suffix))
{
generateFormParametersJavascript(name, entity, tag);
}
}
}
}
}
catch (ClassNotFoundException e)
{
throw new EngineTemplateProcessingException(mTemplate, "couldn't process the " + getEntityName() + " field value tag '" + tag + "', the specified class couldn't be found.", e);
}
catch (NoSuchFieldException e)
{
throw new EngineTemplateProcessingException(mTemplate, "couldn't process the " + getEntityName() + " field value tag '" + tag + "', the field couldn't be found.", e);
}
catch (IllegalAccessException e)
{
throw new EngineTemplateProcessingException(mTemplate, "couldn't process the " + getEntityName() + " field value tag '" + tag + "', the field isn't accessible.", e);
}
catch (ExpectedStringConstantFieldException e)
{
throw new EngineTemplateProcessingException(mTemplate, "couldn't process the " + getEntityName() + " field value tag '" + tag + "' since the referenced field is not a public final static String constant.", e);
}
}
}
}
private void generateQueryUrl(final Entity entity, final String queryValueId)
{
if (mReplaceExistingValues || !mTemplate.isValueSet(queryValueId))
{
mTemplate.setValue(queryValueId, generateEntityQueryUrl(entity).encoder(mEncoder));
mSetValues.add(queryValueId);
}
}
private void generateFormUrl(final String name, final Entity entity, final String formValueId)
{
registerFormUrlTag(name, formValueId);
if (mReplaceExistingValues || !mTemplate.isValueSet(formValueId))
{
mTemplate.setValue(formValueId, generateEntityFormUrl(entity).encoder(mEncoder));
mSetValues.add(formValueId);
}
}
private void generateFormParameters(final String name, final Entity entity, final String paramsValueId)
{
registerFormParamTag(name, paramsValueId);
if (mReplaceExistingValues || !mTemplate.isValueSet(paramsValueId))
{
mTemplate.setValue(paramsValueId, generateEntityFormParameters(entity));
mSetValues.add(paramsValueId);
}
}
private void generateFormParametersJavascript(final String name, final Entity entity, final String paramsjsValueId)
{
registerFormParamTag(name, paramsjsValueId);
if (mReplaceExistingValues || !mTemplate.isValueSet(paramsjsValueId))
{
mTemplate.setValue(paramsjsValueId, generateEntityFormParametersJavascript(entity));
mSetValues.add(paramsjsValueId);
}
}
private void registerFormUrlTag(final String name, final String tag)
{
if (null == mFormUrls)
{
mFormUrls = new LinkedHashMap<String, String>();
}
mFormUrls.put(name, tag);
}
private void registerFormParamTag(final String name, final String tag)
{
if (null == mFormParams)
{
mFormParams = new LinkedHashMap<String, String>();
}
mFormParams.put(name, tag);
}
private void ensurePresenceOfRequiredMatchingTags()
{
// verify that all form tags have matching param tags and
// that for all the param tags a corresponding form tag is present too
if (mFormUrls != null &&
mFormParams != null)
{
// remove all the entries that are present in both maps
for (Iterator<String> urls_it = mFormUrls.keySet().iterator(); urls_it.hasNext(); )
{
String name = urls_it.next();
if (mFormParams.remove(name) != null)
{
urls_it.remove();
}
}
for (Iterator<String> params_it = mFormParams.keySet().iterator(); params_it.hasNext();)
{
String name = params_it.next();
if (mFormUrls.remove(name) != null)
{
params_it.remove();
}
}
}
if (mFormUrls != null &&
mFormUrls.size() > 0)
{
Map.Entry<String, String> first_entry = mFormUrls.entrySet().iterator().next();
throw new EngineTemplateProcessingException(mTemplate, "the form URL tag '" + first_entry.getValue()+ "' was specified for " + getEntityName() + " '" + first_entry.getKey()+ "' without a matching parameter tag, both tags are needed.");
}
if (mFormParams != null &&
mFormParams.size() > 0)
{
Map.Entry<String, String> first_entry = mFormParams.entrySet().iterator().next();
throw new EngineTemplateProcessingException(mTemplate, "the parameters tag '" + first_entry.getValue()+ "' was specified for " + getEntityName() + " '" + first_entry.getKey()+ "' without a matching form URL tag, both tags are needed.");
}
}
}