001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.rebind; 029 030import java.io.PrintWriter; 031import java.util.ArrayList; 032import java.util.List; 033 034import com.google.gwt.core.ext.Generator; 035import com.google.gwt.core.ext.GeneratorContext; 036import com.google.gwt.core.ext.TreeLogger; 037import com.google.gwt.core.ext.UnableToCompleteException; 038import com.google.gwt.core.ext.typeinfo.JClassType; 039import com.google.gwt.core.ext.typeinfo.JMethod; 040import com.google.gwt.core.ext.typeinfo.JType; 041import com.google.gwt.core.ext.typeinfo.NotFoundException; 042import com.google.gwt.core.ext.typeinfo.TypeOracle; 043import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; 044import com.google.gwt.user.rebind.SourceWriter; 045 046/** 047 * This generator class generates a class with a method which calls all static initClass() 048 * methods of classes that implement the {@link org.opencms.gwt.client.I_CmsHasInit} marker interface.<p> 049 * 050 * @since 8.0.0 051 */ 052public class CmsClassInitGenerator extends Generator { 053 054 /** The name of the class to generate. */ 055 private static final String CLASS_NAME = "CmsClassInitializerImpl"; 056 057 /** The name of the interface passed into GWT.create(). */ 058 private static final String INIT_INTERFACE_NAME = "org.opencms.gwt.client.I_CmsClassInitializer"; 059 060 /** The name of the marker interface for the generator. */ 061 private static final String MARKER_INTERFACE_NAME = "org.opencms.gwt.client.I_CmsHasInit"; 062 063 /** The package of the class to generate. */ 064 private static final String PACKAGE_NAME = "org.opencms.gwt.client"; 065 066 /** 067 * @see com.google.gwt.core.ext.Generator#generate(com.google.gwt.core.ext.TreeLogger, com.google.gwt.core.ext.GeneratorContext, java.lang.String) 068 */ 069 @Override 070 public String generate(TreeLogger logger, GeneratorContext context, String typeName) 071 throws UnableToCompleteException { 072 073 TypeOracle oracle = context.getTypeOracle(); 074 JClassType initClass = oracle.findType(MARKER_INTERFACE_NAME); 075 List<JClassType> initTypes = new ArrayList<JClassType>(); 076 for (JClassType subtype : initClass.getSubtypes()) { 077 try { 078 JMethod method = subtype.getMethod("initClass", new JType[] {}); 079 if (!method.isStatic()) { 080 throw new NotFoundException(); 081 } 082 initTypes.add(subtype); 083 } catch (NotFoundException e) { 084 logger.log( 085 TreeLogger.ERROR, 086 "Could not find initClass() method in class " + subtype.getQualifiedSourceName()); 087 throw new UnableToCompleteException(); 088 } 089 } 090 generateClass(logger, context, initTypes); 091 return PACKAGE_NAME + "." + CLASS_NAME; 092 } 093 094 /** 095 * This method generates the source code for the class initializer class.<p> 096 * 097 * @param logger the logger to be used 098 * @param context the generator context 099 * @param subclasses the classes for which the generated code should the initClass() method 100 */ 101 public void generateClass(TreeLogger logger, GeneratorContext context, List<JClassType> subclasses) { 102 103 PrintWriter printWriter = context.tryCreate(logger, PACKAGE_NAME, CLASS_NAME); 104 if (printWriter == null) { 105 return; 106 } 107 ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(PACKAGE_NAME, CLASS_NAME); 108 composer.addImplementedInterface(INIT_INTERFACE_NAME); 109 SourceWriter sourceWriter = composer.createSourceWriter(context, printWriter); 110 sourceWriter.println("public void initClasses() {"); 111 sourceWriter.indent(); 112 for (JClassType type : subclasses) { 113 sourceWriter.println(type.getQualifiedSourceName() + ".initClass();"); 114 } 115 sourceWriter.outdent(); 116 sourceWriter.println("}"); 117 sourceWriter.outdent(); 118 sourceWriter.println("}"); 119 context.commit(logger, printWriter); 120 } 121}