/* * $Id$ * * License Agreement. * * Rich Faces - Natural Ajax for Java Server Faces (JSF) * * Copyright (C) 2007 Exadel, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.richfaces.cdk.templatecompiler; import java.io.IOException; import java.io.Writer; import java.util.Collection; import org.richfaces.cdk.CdkException; import org.richfaces.cdk.CdkWriter; import org.richfaces.cdk.FileManager; import org.richfaces.cdk.Logger; import org.richfaces.cdk.Output; import org.richfaces.cdk.Outputs; import org.richfaces.cdk.generate.freemarker.FreeMarkerRenderer; import org.richfaces.cdk.model.ComponentLibrary; import org.richfaces.cdk.model.ComponentModel; import org.richfaces.cdk.model.ModelSet; import org.richfaces.cdk.model.PropertyBase; import org.richfaces.cdk.model.RenderKitModel; import org.richfaces.cdk.model.RendererModel; import org.richfaces.cdk.templatecompiler.builder.model.JavaClass; import org.richfaces.cdk.templatecompiler.model.CdkFragmentElement; import org.richfaces.cdk.templatecompiler.model.CompositeFragmentImplementation; import org.richfaces.cdk.templatecompiler.model.Template; import com.google.inject.Inject; import freemarker.template.TemplateException; /** * <p class="changed_added_4_0"> * </p> * * @author asmirnov@exadel.com * @author Lukas Fryc */ public class RendererClassGenerator implements CdkWriter { private FileManager output; private Logger log; private TemplateVisitorFactory<RendererClassVisitor> visitorFactory; private FreeMarkerRenderer renderer; /** * <p class="changed_added_4_0"> * </p> * * @param library * @param output * @param log * @param visitorFactory */ @Inject public RendererClassGenerator(@Output(Outputs.JAVA_CLASSES) FileManager output, Logger log, TemplateVisitorFactory<RendererClassVisitor> visitorFactory, @TemplateModel FreeMarkerRenderer renderer) { this.output = output; this.log = log; this.visitorFactory = visitorFactory; this.renderer = renderer; } private ComponentModel findComponentByRenderer(RendererModel renderer, ComponentLibrary library) { return library.getComponentByRenderer(renderer.getFamily(), renderer.getId()); } /* * (non-Javadoc) * * @see org.richfaces.cdk.CdkWriter#render(org.richfaces.cdk.model.ComponentLibrary ) */ @Override public void render(ComponentLibrary library) throws CdkException { for (RenderKitModel renderKit : library.getRenderKits()) { for (RendererModel renderer : renderKit.getRenderers()) { if (renderer.hasChanged()) { Template template = renderer.getTemplate(); if (null != template) { Collection<PropertyBase> attributes = ModelSet.<PropertyBase>create(); ComponentModel component = findComponentByRenderer(renderer, library); if (component != null) { attributes.addAll(component.getAttributes()); } attributes.addAll(renderer.getAttributes()); RendererClassVisitor visitor = visitorFactory.createVisitor(template.getInterface(), attributes); template.getImplementation().beforeVisit(visitor); if (template.getFragments() != null) { for (CdkFragmentElement fragment : template.getFragments()) { CompositeFragmentImplementation implementation = fragment.getFragmentImplementation(); fragment.beforeVisit(visitor); if (implementation != null) { implementation.visit(visitor); } fragment.afterVisit(visitor); } } template.getImplementation().visitChildren(visitor); template.getImplementation().afterVisit(visitor); JavaClass javaClass = visitor.getGeneratedClass(); String fullName = javaClass.getName(); Writer outFile = null; try { outFile = output.createOutput(fullName.replace('.', '/') + ".java", library.lastModified()); if (null != outFile) { this.renderer.writeTemplate("class.ftl", javaClass, outFile); } } catch (IOException e) { throw new CdkException(e); } catch (TemplateException e) { throw new CdkException(e); } finally { if (null != outFile) { try { outFile.close(); } catch (IOException e) { log.warn("IOException occured when closing writer for renderer-class", e); } } } } } } } } }