001/*
002// $Id: //open/util/resgen/src/org/eigenbase/resgen/CppHeaderGenerator.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.File;
026import java.io.PrintWriter;
027
028/**
029 * Generates a C++ header file containing resource definitions.
030 *
031 * @author jhyde
032 * @since 19 September, 2005
033 * @version $Id: //open/util/resgen/src/org/eigenbase/resgen/CppHeaderGenerator.java#3 $
034 */
035public class CppHeaderGenerator extends CppGenerator
036{
037    /**
038     * Creates a C++ header generator.
039     *
040     * @param srcFile
041     * @param file
042     * @param className
043     * @param baseClassName Name of base class, must not be null, typically
044     * @param defaultExceptionClassName
045     */
046    public CppHeaderGenerator(
047        File srcFile,
048        File file,
049        String className,
050        String baseClassName,
051        String defaultExceptionClassName)
052    {
053        super(srcFile, file, className, baseClassName, 
054            defaultExceptionClassName, null);
055    }
056
057    public void generateModule(
058        ResourceGen generator,
059        ResourceDef.ResourceBundle resourceList,
060        PrintWriter pw)
061    {
062        generateDoNotModifyHeader(pw);
063        generateGeneratedByBlock(pw);
064
065        StringBuffer ifndef = new StringBuffer();
066        String fileName = getFile().getName();
067        ifndef.append(fileName.substring(0, fileName.length() - 2));
068        ifndef.append("_Included");
069        if (resourceList.cppNamespace != null) {
070            ifndef.insert(0, '_');
071            ifndef.insert(0, resourceList.cppNamespace.substring(1));
072            ifndef.insert(0, Character.toUpperCase(resourceList
073                                                   .cppNamespace
074                                                   .charAt(0)));
075        }
076
077        pw.println("#ifndef " + ifndef.toString());
078        pw.println("#define " + ifndef.toString());
079        pw.println();
080        pw.println("#include <ctime>");
081        pw.println("#include <string>");
082        pw.println();
083        pw.println("#include \"Locale.h\"");
084        pw.println("#include \"ResourceDefinition.h\"");
085        pw.println("#include \"ResourceBundle.h\"");
086        pw.println();
087
088        pw.println("// begin includes specified by " + getSrcFileForComment());
089        if (resourceList.cppExceptionClassLocation != null) {
090            pw.println("#include \""
091                       + resourceList.cppExceptionClassLocation
092                       + "\"");
093        }
094
095        for(int i = 0; i < resourceList.resources.length; i++) {
096            ResourceDef.Resource resource = resourceList.resources[i];
097
098            if (resource instanceof ResourceDef.Exception) {
099                ResourceDef.Exception exception =
100                    (ResourceDef.Exception)resource;
101
102                if (exception.cppClassLocation != null) {
103                    pw.println("#include \""
104                               + exception.cppClassLocation
105                               + "\"");
106                }
107            }
108        }
109        pw.println("// end includes specified by " + getSrcFileForComment());
110        pw.println();
111        if (resourceList.cppNamespace != null) {
112            pw.println("namespace " + resourceList.cppNamespace + " {");
113            pw.println();
114        }
115
116        pw.println();
117
118        String baseClass = getBaseClassName();
119        String className = getClassName();
120        String bundleCacheClassName = className + "BundleCache";
121
122        pw.println("class " + className + ";");
123        pw.println("typedef map<Locale, " + className + "*> "
124                   + bundleCacheClassName + ";");
125        pw.println();
126        pw.println("class " + className + " : " + baseClass);
127        pw.println("{");
128        pw.println("    protected:");
129        pw.println("    explicit " + className + "(Locale locale);");
130        pw.println();
131        pw.println("    public:");
132        pw.println("    virtual ~" + className + "() { }");
133        pw.println();
134        pw.println("    static const " + className + " &instance();");
135        pw.println("    static const "
136                   + className
137                   + " &instance(const Locale &locale);");
138        pw.println();
139
140        pw.println("    static void setResourceFileLocation(const std::string &location);");
141        pw.println();
142
143        for(int i = 0; i < resourceList.resources.length; i++) {
144            ResourceDef.Resource resource = resourceList.resources[i];
145
146            String text = resource.text.cdata;
147            String comment = ResourceGen.getComment(resource);
148            String parameterList = getParameterList(text);
149
150            // e.g. "Internal"
151            final String resourceInitCap =
152                ResourceGen.getResourceInitcap(resource);
153
154            Util.generateCommentBlock(pw, resource.name, text, comment);
155
156            pw.println("    std::string " + resource.name + "("
157                       + parameterList + ") const;");
158
159            if (resource instanceof ResourceDef.Exception) {
160                ResourceDef.Exception exception =
161                    (ResourceDef.Exception)resource;
162
163                String exceptionClass = exception.cppClassName;
164                if (exceptionClass == null) {
165                    exceptionClass = resourceList.cppExceptionClassName;
166                }
167
168                pw.println("    " + exceptionClass
169                           + "* new" + resourceInitCap + "("
170                           + parameterList + ") const;");
171
172                boolean chainExceptions =
173                    (exception.cppChainExceptions != null &&
174                     exception.cppChainExceptions.equalsIgnoreCase("true"));
175
176                if (chainExceptions) {
177                    if (parameterList.length() > 0) {
178                        pw.println("    "
179                                   + exceptionClass
180                                   + "* new"
181                                   + resourceInitCap
182                                   + "("
183                                   + parameterList
184                                   + ", const "
185                                   + exceptionClass
186                                   + " * const prev) const;");
187                    } else {
188                        pw.println("  "
189                                   + exceptionClass
190                                   + " new"
191                                   + resourceInitCap + "("
192                                   + "const "
193                                   + exceptionClass
194                                   + " * const prev) const;");
195                    }
196                }
197            }
198
199            pw.println();
200        }
201
202        pw.println("    private:");
203        for(int i = 0; i < resourceList.resources.length; i++) {
204            ResourceDef.Resource resource = resourceList.resources[i];
205
206            pw.println("    ResourceDefinition _" + resource.name + ";");
207        }
208        pw.println();
209
210        pw.println("    template<class _GRB, class _BC, class _BC_ITER>");
211        pw.println("        friend _GRB *makeInstance(_BC &bundleCache, const Locale &locale);");
212
213        pw.println("};");
214
215
216        if (resourceList.cppNamespace != null) {
217            pw.println();
218            pw.println("} // end namespace " + resourceList.cppNamespace);
219        }
220
221        pw.println();
222        pw.println("#endif // " + ifndef.toString());
223    }
224
225}
226
227// End CppHeaderGenerator.java