/* * Copyright 2013 eXo Platform SAS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package examples.plugin.bundlegen.impl; import examples.plugin.bundlegen.BundleGen; import juzu.impl.common.Name; import juzu.impl.common.Path; import juzu.impl.compiler.ElementHandle; import juzu.impl.compiler.MessageCode; import juzu.impl.compiler.ProcessingContext; import juzu.impl.metamodel.AnnotationKey; import juzu.impl.metamodel.AnnotationState; import juzu.impl.plugin.application.metamodel.ApplicationMetaModel; import juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin; import javax.lang.model.element.PackageElement; import javax.tools.FileObject; import javax.tools.JavaFileObject; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Level; /** * @author Julien Viet */ public class BundleGenMetaModelPlugin extends ApplicationMetaModelPlugin { // tag::BUNDLE_NOT_FOUND[] public static final MessageCode BUNDLE_NOT_FOUND = new MessageCode("BUNDLE_NOT_FOUND", "The bundle %1$s cannot be resolved"); // end::BUNDLE_NOT_FOUND[] // tag::CANNOT_CREATE_BUNDLE[] public static final MessageCode CANNOT_CREATE_BUNDLE = new MessageCode("CANNOT_CREATE_BUNDLE", "The bundle %1$s cannot be created"); // end::CANNOT_CREATE_BUNDLE[] /** . */ private HashMap<ElementHandle.Package, String> bundles = new HashMap<ElementHandle.Package, String>(); // tag::constructor[] public BundleGenMetaModelPlugin() { super("bundlegen"); } // end::constructor[] // tag::init[] @Override public Set<Class<? extends Annotation>> init(ProcessingContext env) { return Collections.<Class<? extends Annotation>>singleton(BundleGen.class); } // end::init[] // tag::processAnnotationAdded[] @Override public void processAnnotationAdded(ApplicationMetaModel application, AnnotationKey key, AnnotationState added) { Name type = key.getType(); if (type.toString().equals(BundleGen.class.getName())) { ElementHandle.Package pkg = (ElementHandle.Package)key.getElement(); bundles.put(pkg, (String)added.get("value")); } } // end::processAnnotationAdded[] // tag::processAnnotationRemoved[] @Override public void processAnnotationRemoved(ApplicationMetaModel application, AnnotationKey key, AnnotationState removed) { Name type = key.getType(); if (type.toString().equals(BundleGen.class.getName())) { ElementHandle.Package pkg = (ElementHandle.Package)key.getElement(); bundles.remove(pkg); } } // end::processAnnotationRemoved[] // tag::prePassivate[] @Override public void prePassivate(ApplicationMetaModel application) { for (Map.Entry<ElementHandle.Package, String> entry : bundles.entrySet()) { ElementHandle.Package pkg = entry.getKey(); String bundleName = entry.getValue(); processBundle(application, pkg, bundleName); } } // end::prePassivate[] // tag::processBundle[] private void processBundle(ApplicationMetaModel application, ElementHandle.Package pkg, String bundleName) { ProcessingContext context = application.getProcessingContext(); PackageElement pkgElt = context.get(pkg); Properties properties = loadBundle(context, pkg, bundleName); if (properties == null) { throw BUNDLE_NOT_FOUND.failure(pkgElt, bundleName); } else { try { generateBundleClass(context, properties, pkgElt, bundleName); } catch (IOException e) { throw CANNOT_CREATE_BUNDLE.failure(pkgElt, bundleName).initCause(e); } } } // end::processBundle[] // tag::loadBundle[] private Properties loadBundle(ProcessingContext context, ElementHandle.Package pkg, String bundleName) { Path.Absolute absolute = pkg.getPackageName().resolve(bundleName + ".properties"); FileObject bundle = context.resolveResourceFromSourcePath(pkg, absolute); if (bundle != null) { try { InputStream in = bundle.openInputStream(); Properties properties = new Properties(); properties.load(in); return properties; } catch (IOException e) { context.log(Level.SEVERE, "Could not load resource bundle", e); } } return null; } // end::loadBundle[] // tag::generateBundleClass[] private void generateBundleClass(ProcessingContext context, Properties properties, PackageElement pkgElt, String bundleName) throws IOException { String fqn = pkgElt.getQualifiedName() + "." + bundleName; JavaFileObject source = context.createSourceFile(fqn, pkgElt); PrintWriter writer = new PrintWriter(source.openWriter()); writer.println("package " + pkgElt.getQualifiedName() + ";"); writer.println("import examples.plugin.bundlegen.impl.BundleResolver;"); writer.println("public class " + bundleName + " {"); for (String key : properties.stringPropertyNames()) { writer.println("public static String " + key + "() {"); writer.println("return BundleResolver.resolve(" + bundleName + ".class, \"" + key + "\");"); writer.println("}"); } writer.println("}"); writer.close(); } // end::generateBundleClass[] }