001/*
002// $Id: //open/util/resgen/src/org/eigenbase/resgen/AbstractGenerator.java#3 $
003// Package org.eigenbase.resgen is an i18n resource generator.
004// Copyright (C) 2005-2005 The Eigenbase Project
005// Copyright (C) 2005-2005 Disruptive Tech
006// Copyright (C) 2005-2005 LucidEra, Inc.
007// Portions Copyright (C) 2001-2005 Kana Software, Inc. and others.
008//
009// This library is free software; you can redistribute it and/or modify it
010// under the terms of the GNU Lesser General Public License as published by the
011// Free Software Foundation; either version 2 of the License, or (at your
012// option) any later version approved by The Eigenbase Project.
013//
014// This library is distributed in the hope that it will be useful, 
015// but WITHOUT ANY WARRANTY; without even the implied warranty of
016// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017// GNU Lesser General Public License for more details.
018// 
019// You should have received a copy of the GNU Lesser General Public License
020// along with this library; if not, write to the Free Software
021// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022*/
023package org.eigenbase.resgen;
024
025import java.io.PrintWriter;
026import java.io.File;
027import java.util.Date;
028import java.text.Format;
029import java.text.MessageFormat;
030import java.text.NumberFormat;
031import java.text.DateFormat;
032import java.lang.reflect.Method;
033import java.lang.reflect.InvocationTargetException;
034
035/**
036 * Abstract base for all generators.
037 *
038 * @author jhyde
039 * @since 19 September, 2005
040 * @version $Id: //open/util/resgen/src/org/eigenbase/resgen/AbstractGenerator.java#3 $
041 */
042abstract class AbstractGenerator implements Generator
043{
044    private final File srcFile;
045    private final File file;
046    private Boolean scmSafeComments = null;
047
048    public AbstractGenerator(File srcFile, File file)
049    {
050        this.srcFile = srcFile;
051        this.file = file;
052    }
053
054    public void setScmSafeComments(boolean enabled)
055    {
056        if (scmSafeComments != null) {
057            throw new AssertionError(
058                "SCM safe comment style may only be configured once.");
059        }
060
061        scmSafeComments = enabled ? Boolean.TRUE : Boolean.FALSE;
062    }
063
064    protected boolean useScmSafeComments()
065    {
066        return scmSafeComments != null && scmSafeComments.booleanValue();
067    }
068
069    /**
070     * Generates code for a particular resource.
071     */
072    protected abstract void generateResource(
073        ResourceDef.Resource resource,
074        PrintWriter pw);
075
076    protected void generateDoNotModifyHeader(PrintWriter pw) {
077        if (useScmSafeComments()) {
078            pw.println(
079                "// This class is generated. Do NOT modify it manually.");
080        } else {
081            pw.println("// This class is generated. Do NOT modify it, or");
082            pw.println("// add it to source control.");
083        }
084        pw.println();
085    }
086
087    protected void generateGeneratedByBlock(PrintWriter pw) {
088        pw.println("/**");
089        pw.println(" * This class was generated");
090        pw.println(" * by " + ResourceGen.class);
091
092        String file = getSrcFileForComment();
093        pw.println(" * from " + file);
094        if (!useScmSafeComments()) {
095            pw.println(" * on " + new Date().toString() + ".");
096        }
097        pw.println(" * It contains a list of messages, and methods to");
098        pw.println(" * retrieve and format those messages.");
099        pw.println(" */");
100        pw.println();
101    }
102
103    /**
104     * Returns the generator's output file.  e.g., "BirthdayResource.java"
105     */
106    protected File getFile()
107    {
108        return file;
109    }
110
111    /**
112     * Returns the XML or .properties source file, in a manner suitable
113     * for use in source code comments.  Path information is stripped if
114     * SCM-safe comment style is enabled.
115     * 
116     * @see #setScmSafeComments(boolean)
117     */
118    protected String getSrcFileForComment()
119    {
120        String filename = srcFile.toString().replace('\\', '/');
121        
122        if (useScmSafeComments()) {
123            int slashPos = filename.lastIndexOf('/');
124            if (slashPos > 0) {
125                filename = "..." + filename.substring(slashPos);
126            }
127        }
128        
129        return filename;
130    }
131    
132    /**
133     * Returns the fully-qualified name of the class being generated,
134     * for example "happy.BirthdayResource_en_US".
135     */
136    protected abstract String getClassName();
137
138    /**
139     * Returns the fully-qualified name of the base class.
140     */
141    protected abstract String getBaseClassName();
142
143    /**
144     * Returns a parameter list string, e.g. "String p0, int p1".
145     */
146    protected String getParameterList(String message) {
147        final String [] types = getArgTypes(message);
148        if (types.length == 0) {
149            return "";
150        }
151        StringBuffer sb = new StringBuffer();
152        for (int i = 0; i < types.length; i++) {
153            String type = types[i];
154            if (i > 0) {
155                sb.append(", ");
156            }
157            sb.append(type);
158
159            // If this is a C++ pointer type, say "const char *", don't put
160            // a space between it and the variable name.
161            if (!type.endsWith("&") && !type.endsWith("*")) {
162                sb.append(" ");
163            }
164            sb.append("p");
165            sb.append(Integer.toString(i));
166        }
167        return sb.toString();
168    }
169
170    /**
171     * Returns the number and types of parameters in the given error message,
172     * expressed as an array of Strings (legal values are
173     * currently "String", "Number", "java.util.Date", and null) ordered by
174     * parameter number.
175     */
176    protected abstract String [] getArgTypes(String message);
177
178    protected String getArgumentList(String message)
179    {
180        final String [] types = getArgTypes(message);
181
182        if (types.length == 0) {
183            return "";
184        }
185
186        StringBuffer sb = new StringBuffer();
187        for (int i = 0; i < types.length; i++) {
188            if (i > 0) {
189                sb.append(", ");
190            }
191            sb.append("p");
192            sb.append(Integer.toString(i));
193        }
194        return sb.toString();
195    }
196
197}
198
199// End AbstractGenerator.java