/*
* Name: GenericPreparer
* Authors: Richard Rodger
*
* Copyright (c) 2004-2006 Richard Rodger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
// package
package org.jostraca.process;
// import
import org.jostraca.Property;
import org.jostraca.DefaultPropertySets;
import org.jostraca.Template;
import org.jostraca.TemplatePath;
import org.jostraca.TemplateException;
import org.jostraca.util.FileUtil;
import org.jostraca.util.Standard;
import org.jostraca.util.ErrorUtil;
import org.jostraca.util.ValueSet;
import org.jostraca.util.ValueCode;
import org.jostraca.util.PropertySet;
import org.jostraca.util.PropertySetManager;
import org.jostraca.util.PropertySetModifierManager;
import java.util.List;
import java.io.File;
/** Processing class for preparing the generation process by setting special properties.
*/
public class GenericPreparer extends TemplateHandlerSupport {
public static final char[] sCanonicalTemplateFileNameChars = new char[] {
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','u','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','U','R','S','T','U','V','W','X','Y','Z',
'1','2','3','4','5','6','7','8','9','0','$','_'
};
protected PropertySetModifierManager iPropertySetModifierManager = new PropertySetModifierManager();
protected PropertySetManager iLangPSM = DefaultPropertySets.makeLang();
public GenericPreparer() {
// do nothing
}
protected void processImpl( Template pTemplate ) {
Template template = pTemplate;
PropertySet tmps = pTemplate.getMergedPropertySet();
String codeWriterLang = template.getCodeWriterLang();
//t.track( "codeWriterLang", codeWriterLang );
PropertySet langPS = loadLangPropertySet( codeWriterLang, tmps );
iUserMessageHandler.debug( "Template Script:", codeWriterLang );
template.setPropertySet( CONF_lang, langPS );
// prepare settings
handleCodeWriterName( template );
overridePropertySet( template, iPropertySetModifierManager );
template.modifyForOldVersion();
validateMergedPropertySet( template.getMergedPropertySet() );
tmps = template.getMergedPropertySet();
TemplatePath tp = template.getTemplatePath();
dumpPropertySet( tmps, tp );
dumpTemplateSource( tmps, tp, template );
}
protected void completeImpl( List pTemplateList ) {
// do nothing
}
public static void handleCodeWriterName( Template pTemplate ) {
PropertySet mps = pTemplate.getMergedPropertySet();
PropertySet ops = pTemplate.getPropertySet( CONF_override );
// if codewriter not defined use template name + Writer
if( ! mps.isDefined( Property.main_CodeWriter ) ) {
String templateFileName = mps.get( Property.jostraca_template_file );
templateFileName = FileUtil.removeExtension( templateFileName );
templateFileName = makeCanonicalTemplateFileName( templateFileName );
ops.set( Property.main_CodeWriter, templateFileName+FILE_EXT_Writer );
}
}
/** Insert system properties into current PropertySet */
public static void overridePropertySet( Template pTemplate, PropertySetModifierManager pPSMM ) {
PropertySet mps = pTemplate.getMergedPropertySet();
PropertySet ops = pTemplate.getPropertySet( CONF_override );
// set system defaults if not defined
// propName => propDefault
String[] sysProps = {
Property.jostraca_system_pathSeparator, File.pathSeparator
,Property.jostraca_system_fileSeparator, File.separator
};
String sysPropName;
String sysPropDefault;
int numProps = sysProps.length / 2;
for( int propI = 0; propI < numProps; propI++ ) {
sysPropName = sysProps[ propI * 2 ];
sysPropDefault = sysProps[ (propI * 2) + 1 ];
if( ! mps.isDefined( sysPropName ) ) {
ops.set( sysPropName, sysPropDefault );
}
}
// if outputfolder not defined use current folder
if( ! mps.isDefined( Property.main_OutputFolder ) ) {
ops.set( Property.main_OutputFolder, Standard.DOT );
}
// get canonical form for MakeBackup
if( mps.isYes( Property.main_MakeBackup ) ) {
ops.set( Property.jostraca_MakeBackup, mps.get( Property.lang_TrueString ) );
}
else {
ops.set( Property.jostraca_MakeBackup, mps.get( Property.lang_FalseString ) );
}
if( null != pPSMM ) {
// perform modifications on PropertySet
String modClasses = mps.get( Property.jostraca_properties_modifiers );
//t.track( "modClasses", modClasses );
if( mps.has( Property.jostraca_properties_modifiers ) ) {
pPSMM.loadPropertySetModifierClasses( modClasses );
pPSMM.modify( mps, ops );
}
}
//t.track( "modifyPropertySet.pPropertySet.size", pPropertySet.size() );
}
/** Load lang PropertySet based on lang code.
* Return an empty property set if not found.
* @param pLangCode Used to find file in lang config folder: lang.conf
*/
private PropertySet loadLangPropertySet( String pLangCode, PropertySet pPropertySet ) {
PropertySet langPS = new PropertySet();
// FIX: need a decoupled way to access config as may not have file system!
String configFolder = pPropertySet.get( Property.jostraca_ConfigFolder );
File langPropFilePath = new File( configFolder, buildLangConfigFileName( pLangCode ) );
try {
langPS = iLangPSM.load( pLangCode, langPropFilePath, PropertySetManager.USE_DEFAULT_IF_FILE_DOES_NOT_EXIST );
}
catch( Exception e ) {
ErrorUtil.nonFatalException( e );
}
return langPS;
}
/** Validate merged PropertySet.
* REVIEW: what relation to Jostraca.validateConfig?
* @param pPropertySet PropertySet to be validated.
*/
private void validateMergedPropertySet( PropertySet pPropertySet ) throws TemplateException {
// this expression defaults to "yes" unless strict_version actually equals "no"
if( ! pPropertySet.isNo( Property.jostraca_strict_version ) ) {
// check version number - only accept current version
// this may change as time progresses to something more useful
String version = pPropertySet.get( Property.main_JostracaVersion );
if( ! version.startsWith( VERSION_NUMBER ) ) {
if( version.startsWith( "0." ) ) {
// attempt version in same major version
}
else {
throw new TemplateException( TemplateException.CODE_bad_version,
new String[] { "template_version", version, "expected_version", VERSION_NUMBER } );
}
}
}
}
/** Delete all non-canonical chars. Makes filenames usable as Java class names. */
private static String makeCanonicalTemplateFileName( String pTemplateFileName ) {
String tfn = pTemplateFileName;
if( null == tfn ) {
tfn = Standard.EMPTY;
}
StringBuffer canonicalB = new StringBuffer( tfn.length() );
int numChars = tfn.length();
next_char:
for( int cI = 0; cI < numChars; cI++ ) {
char c = tfn.charAt(cI);
for( int tI = 0; tI < sCanonicalTemplateFileNameChars.length; tI++ ) {
if( c == sCanonicalTemplateFileNameChars[tI] ) {
if( 0 == cI ) {
c = Character.toUpperCase( c );
}
canonicalB.append( c );
continue next_char;
}
}
}
return canonicalB.toString();
}
/** Build lang config file name: append .conf
* @param pLangCode Code name of language.
*/
private String buildLangConfigFileName( String pLangCode ) {
return Standard.EMPTY + pLangCode + FILE_EXT_conf;
}
/** Dump property set to external file in the output folder. */
private void dumpPropertySet( PropertySet pPropertySet, TemplatePath pTemplatePath ) {
if( pPropertySet.isYes( Property.main_DumpPropertySet ) ) {
String dumpFile = Standard.EMPTY;
try {
dumpFile
= pPropertySet.get( Property.main_OutputFolder, Standard.DOT )
+ File.separator
+ pTemplatePath.getTemplateFileName() + "-jostraca-settings.txt"
;
pPropertySet.save( dumpFile );
}
catch( Exception e ) {
throw ProcessException.CODE_dump_ps( new ValueSet( ValueCode.FILE, dumpFile ), e );
}
}
}
/** Dump template source to external file in the output folder. */
private void dumpTemplateSource( PropertySet pPropertySet,
TemplatePath pTemplatePath,
Template pTemplate )
{
if( pPropertySet.isYes( Property.main_DumpTemplate ) ) {
String dumpFile = Standard.EMPTY;
try {
dumpFile
= pPropertySet.get( Property.main_OutputFolder, Standard.DOT )
+ File.separator
+ pTemplatePath.getTemplateFileName() + "-template-source.txt"
;
FileUtil.writeFile( dumpFile, pTemplate.getSource() );
}
catch( Exception e ) {
throw ProcessException.CODE_dump_tm( new ValueSet( ValueCode.FILE, dumpFile ), e );
}
}
}
}