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    */
023    package org.eigenbase.resgen;
024    
025    import java.io.File;
026    import 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     */
035    public 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