/* XBN Java: Generically useful, non-GUI Java code. http://sourceforge.net/projects/xbnjava Copyright (C) 1997-2003, Jeff Epstein All rights reserved. Modifications: No Redistribution in binary form, with or without modifications, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * If modifications are made to source code then this license should indicate that fact in the "Modifications" section above. * Neither the author, nor the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [NOTE: This license contains NO advertising clause.] */ package xbn.template; import xbn.XBNObject; import xbn.array.AOSLHashtable; import xbn.array.UniqueStringAP; import xbn.array.primitive.ListPA; import xbn.named.Named; import xbn.util.ForLineRetrieval; /**
A template is text that contains one or more \~G\~gaps\~EG\~, each representing a piece of information whose value is populated at runtime.
Source code: Template.java. Example code See the example code for TemplateFiller
For the sake of this documentation, it is assumed that the gap tag delimiter is '\~
', the text for the gap start and end tags is "G
" and "EG
", respectively, and the escape character is '\\\\
'. Use GapConfig to configure different values.
\~G\~GAPNAME\~EG\~
TConfigDefaults.getMaxGapNameLength
characters in length (inclusive). It is recommended that all gap names be enforced to be only letters, digits and underscores, but you need to enforce this on your own.\\
'. This is useful for recursive templates: \\\~G\\\~sub_gap\\\~EG\\\~
\\
' must also be escaped (by itself) in order to be displayed literally.Read the documentation for the various functions in TemplateData.
Pretend this is your template:
Hello there \~G\~name_first\~EG\~ \~G\~name_last\~EG\~
I hope things are going well for you, \~G\~name_first\~EG\~.
Love, Me.
In order, the absolute gaps are: name_first, name_last, name_first
And the unique gaps are: name_first, name_last
Note that for every space before and after absolute gaps, there is a surrounding text element. In other words, the number of surrounding text elements is always exactly one more that the number of absolute gaps.
@version 0.9b @author Jeff Epstein, http://sourceforge.net/projects/xbnjava. **/ public class Template extends XBNObject implements Named { TemplateData tData = null; private TFilter tFilter = null; /**Create a Template.
Equal to Template(null, flr_srcTxt)
Create a Template.
Equal to Template(s_name, flr_srcTxt, (new TParseConfig()))
Create a Template.
Equal to Template(null, flr_srcTxt, tp_config, null)
Create a Template.
Equal to Template(s_name, flr_srcTxt, tp_config, null)
Create a Template.
Equal to Template(null, flr_srcTxt, tp_config, template_filter)
Create a Template.
@param s_templateName The name of the template. See getName @param flr_srcTxt The source text for this Template. May not be null. @param tp_config The configuration defining a gap. May not be null. @param template_filter The TFilter used to enforce the integrity of the about-to-be-retrieved template text. If null, no restrictions are imposed. See getTFilter. **/ public Template(String s_name, ForLineRetrieval flr_srcTxt, TParseConfig tp_config, TFilter template_filter) throws TemplateFormatException { TemplateDataOrString tdos = new TemplateDataOrString(s_name, flr_srcTxt, tp_config); //Using getName() will throw a NullPointerException...START if(!tdos.isTemplate()) { throw new TemplateFormatException("constructor: There are no gaps in the provided template text. TemplateDataOrString.isTemplate() equals false."); } tData = tdos.getTemplateData(); //Using getName() will throw a NullPointerException...END if(template_filter != null && !template_filter.isTemplateValid(this)) { throwTFX(sCNSTR, "This template is invalid according to template_filter.isTemplateValid(). Check that all required gaps (in template_filter) actually exist in 'this' Template, and that there are no extras.\ntemplate_filter.toString()=\n[" + template_filter.toString() + "]\nthis.toString()\n[" + toString() + "]."); } tFilter = template_filter; } /**Create a copy of the provided Template.
@param t_emplate The Tempate to copy. May not be null. **/ public Template(Template t_emplate) { try { tData = t_emplate.tData.getTDClone(); } catch(NullPointerException npx) { throwAX("constructor: t_emplate is null."); } tFilter = t_emplate.tFilter; } /**Create a Template.
@param template_data The TempateData. May not be null. **/ public Template(TemplateData template_data) { throwAXIfNull(template_data, "template_data", sCNSTR); tData = template_data; } /**Get the TFilter for direct manipulation.
This is only used in the constructor, but is referenced here for giggles.
**/ public final TFilter getTFilter() { return tFilter; } /**Get the TemplateData for direct manipulation.
**/ public final TemplateData getTemplateData() { return tData; } /**Get the AOSLHashtable for direct manipulation.
@returngetTemplateData().getAOSLookup().getAOSLHashtable()
**/
public final AOSLHashtable getAOSLHashtable() {
return getTemplateData().getAOSLookup().getAOSLHashtable();
}
/**
Get the UniqueStringAP, which contains all unique gaps.
@returngetTemplateData().getAOSLookup().getUSAPUnique()
**/
public final UniqueStringAP getUSAPUnique() {
return getTemplateData().getAOSLookup().getUSAPUnique();
}
/**
Get the UniqueStringAP, which contains all absolute gaps.
@returngetTemplateData().getAOSLookup().getUSAPAbsolute()
**/
public final UniqueStringAP getUSAPAbsolute() {
return getTemplateData().getAOSLookup().getUSAPAbsolute();
}
/**
Get a listing of the unique gap names.
@return(new ListPA()).get(getUSAPUnique().getUniqueStringPAS())
**/
public String getListUnq() {
return (new ListPA()).get(getUSAPUnique().getUniqueStringPAS());
}
/**
Get a listing of the unique gap names.
@return(new ListPA(s_divider)).get(getUSAPUnique().getUniqueStringPAS())
**/
public String getListUnq(String s_divider) {
return (new ListPA(s_divider)).get(getUSAPUnique().getUniqueStringPAS());
}
/**
Get a listing of the unique gap names.
@return(new ListPA(s_prefix, s_postfix)).get(getUSAPUnique().getUniqueStringPAS())
**/
public String getListUnq(String s_prefix, String s_postfix) {
return (new ListPA(s_prefix, s_postfix)).get(getUSAPUnique().getUniqueStringPAS());
}
/**
Get a listing of the unique gap names.
@return(new ListPA(s_prefix, s_divider, s_postfix)).get(getUSAPUnique().getUniqueStringPAS())
**/
public String getListUnq(String s_prefix, String s_divider, String s_postfix) {
return (new ListPA(s_prefix, s_divider, s_postfix)).get(getUSAPUnique().getUniqueStringPAS());
}
/**
Get a listing of the absolute gap names.
@return(new ListPA()).get(getUSAPAbsolute().getUniqueStringPAS())
**/
public String getListAbs() {
return (new ListPA()).get(getUSAPAbsolute().getUniqueStringPAS());
}
/**
Get a listing of the absolute gap names.
@return(new ListPA(s_divider)).get(getUSAPAbsolute().getUniqueStringPAS())
**/
public String getListAbs(String s_divider) {
return (new ListPA(s_divider)).get(getUSAPAbsolute().getUniqueStringPAS());
}
/**
Get a listing of the absolute gap names.
@return(new ListPA(s_prefix, s_postfix)).get(getUSAPAbsolute().getUniqueStringPAS())
**/
public String getListAbs(String s_prefix, String s_postfix) {
return (new ListPA(s_prefix, s_postfix)).get(getUSAPAbsolute().getUniqueStringPAS());
}
/**
Get a listing of the absolute gap names.
@return(new ListPA(s_prefix, s_divider, s_postfix)).get(getUSAPAbsolute().getUniqueStringPAS())
**/
public String getListAbs(String s_prefix, String s_divider, String s_postfix) {
return (new ListPA(s_prefix, s_divider, s_postfix)).get(getUSAPAbsolute().getUniqueStringPAS());
}
/**
Given the provided absolute gap's array index, what is the array index for the corresponding unique gap?
@returngetUSAPAbsolute().getUniqueString(i_absArrIdx).getUnqArrIdx()
**/
public final int getUnqArrIdxFromAbs(int i_absArrIdx) {
return getUSAPAbsolute().getUniqueString(i_absArrIdx).getUnqArrIdx();
}
/**
From the absolute-to-unique-gap-map array, get the unique gap array index for the requested absolute gap.
Pretend this is your template:
Hello there \~G\~name_first\~EG\~ \~G\~name_last\~EG\~
I hope things are going well for you, \~G\~name_first\~EG\~.
Love, Me.
Here is a complete listing of all the surrounding text elements:
"Hello there "
" "
"[NEWLINE]I hope things are going well for you, "
".[NEWLINE]Love, Me."
Note that for every space between surrounding text elements, there is an absolute gap. In other words, the number of absolute gaps is always exactly one less that the number of surrounding text elements.
For an in-depth description of all the internal Template objects, see TemplateData.
@return[internal TemplateData].getAOSSurroundingText().getString(i_dx)
**/
public String getSurroundingText(int i_dx) {
return getTemplateData().getAPSSurrText().getString(i_dx);
}
/**
How many surrounding text elements exist in this template?. This will always return a number exactly one greater than the number of absolute gaps.
For an in-depth description of all the internal Template objects, see TemplateData.
@return[internal TemplateData].getAOSSurroundingText().getLength()
**/
public int getSurroundingTextCount() {
//SANITY CHECK...start
// if(getTemplateData().getAPSSurrText().getLength() != (getUSAPUnique().getLength() + 1)) {
// throwAX("getSurroundingTextCount SANITY CHECK: getTemplateData().getAPSSurrText().getLength() (" + getTemplateData().getAPSSurrText().getLength() + ") must equal [getUSAPUnique().getLength() + 1] (" + (getUSAPUnique().getLength() + 1) + ")!");
// }
//SANITY CHECK...end
return getTemplateData().getAPSSurrText().getLength();
}
//REQUIRED BY xbn.named.Named...START
public String getName() {
return getTemplateData().getName();
}
//REQUIRED BY xbn.named.Named...END
/**
Get some information about this Template.
**/ public String toString() { return this.getClass().getName() + ": getName()=" + getName() + ", unique gaps: ['" + getListUnq("', '") + "'], absolute gap array indexes: ['" + getListAbs("', '") + "'], surrounding text: [NOT DISPLAYED. MUST MANUALLY GET VIA getSurroundingText()]"; } /**Throw a TemplateFormatException with a standardized message.
Equal to throw new TemplateFormatException(s_callingFunc, getName(), s_message)
Throw a TemplateFormatException with a standardized message.
Equal to throw new TemplateFormatException(s_callingFunc + (getName()==null?"":" [getName()=" + getName() + "]") + s_message)
Throw an AssertException.
Equal to throwAX(s_callingFunc + (getName()==null?"":" [getName()=" + getName() + "]") + s_message)