/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.util; import org.apache.commons.io.FileUtils; import org.eclipse.che.ide.dto.ClientDtoFactoryVisitor; import org.reflections.Reflections; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import static org.eclipse.che.util.IgnoreUnExistedResourcesReflectionConfigurationBuilder.*; /** * Generates {DtoFactoryVisitorRegistry} class source. * * @author Artem Zatsarynnyi */ public class DtoFactoryVisitorRegistryGenerator { /** * Path of the output class, it definitely should already exits. To ensure proper config. * File content will be overridden. */ protected static final String REGISTRY_PATH = "org/eclipse/che/ide/client/DtoFactoryVisitorRegistry.java"; /** Map containing <FullFQN, ClassName> */ protected static final Map<String, String> dtoFactoryVisitors = new HashMap<>(); /** * Entry point. --rootDir is the optional parameter. * * @param args * @throws IOException */ public static void main(String[] args) throws IOException { File rootFolder = GeneratorUtils.getRootFolder(args); System.out.println(" ------------------------------------------------------------------------ "); System.out.println("Searching for DTO"); System.out.println(" ------------------------------------------------------------------------ "); // find all DtoFactoryVisitors findDtoFactoryVisitors(); generateExtensionManager(rootFolder); } /** * Find all the Java classes that have proper @ClientDtoFactoryVisitor annotation. * * @throws java.io.IOException */ @SuppressWarnings("unchecked") private static void findDtoFactoryVisitors() throws IOException { Reflections reflection = new Reflections(getConfigurationBuilder()); Set<Class<?>> classes = reflection.getTypesAnnotatedWith(ClientDtoFactoryVisitor.class); int i = 0; for (Class clazz : classes) { dtoFactoryVisitors.put(clazz.getCanonicalName(), "provider_" + i++); System.out.println(String.format("New DtoFactoryVisitor found: %s", clazz.getCanonicalName())); } System.out.println(String.format("Found: %d DtoFactoryVisitor(s)", dtoFactoryVisitors.size())); } /** * Generate to source of the class. * * @param rootFolder */ public static void generateExtensionManager(File rootFolder) throws IOException { File outFile = new File(rootFolder, REGISTRY_PATH); StringBuilder builder = new StringBuilder(); builder.append("package org.eclipse.che.ide.client;\n\n"); generateImports(builder); generateClass(builder); // flush content FileUtils.writeStringToFile(outFile, builder.toString()); } /** * Generate imports. * * @param builder */ public static void generateImports(StringBuilder builder) { builder.append("import com.google.inject.Inject;\n"); builder.append("import com.google.inject.Provider;\n"); builder.append("import com.google.inject.Singleton;\n"); builder.append("import java.util.HashMap;\n"); builder.append("import java.util.Map;\n"); } /** * Generate class declarations. * * @param builder */ public static void generateClass(StringBuilder builder) { // generate class header builder.append("/**\n"); builder.append(" * THIS CLASS WILL BE OVERRIDDEN BY MAVEN BUILD. DON'T EDIT CLASS, IT WILL HAVE NO EFFECT.\n"); builder.append(" */\n"); builder.append("@Singleton\n"); builder.append("@SuppressWarnings(\"rawtypes\")\n"); builder.append("public class DtoFactoryVisitorRegistry\n"); builder.append("{\n"); builder.append("\n"); // field builder.append(GeneratorUtils.TAB) .append("/** Contains the map with all the DtoFactoryVisitor Providers <FullClassFQN, Provider>. */\n"); builder.append(GeneratorUtils.TAB).append("protected final Map<String, Provider> providers = new HashMap<>();\n\n"); // generate constructor builder.append(GeneratorUtils.TAB).append("/** Constructor that accepts all found DtoFactoryVisitor Providers. */\n"); builder.append(GeneratorUtils.TAB).append("@Inject\n"); builder.append(GeneratorUtils.TAB).append("public DtoFactoryVisitorRegistry(\n"); // paste args here Iterator<Entry<String, String>> entryIterator = dtoFactoryVisitors.entrySet().iterator(); while (entryIterator.hasNext()) { // <FullFQN, ClassName> Entry<String, String> entry = entryIterator.next(); String hasComma = entryIterator.hasNext() ? "," : ""; // add constructor argument like: // fullFQN classNameToLowerCase, String classFQN = String.format("Provider<%s>", entry.getKey()); String variableName = entry.getValue().toLowerCase(); builder.append(GeneratorUtils.TAB2).append(classFQN).append(" ").append(variableName).append(hasComma).append("\n"); } builder.append(GeneratorUtils.TAB).append(")\n"); builder.append(GeneratorUtils.TAB).append("{\n"); // paste add here for (Entry<String, String> entries : dtoFactoryVisitors.entrySet()) { String fullFqn = entries.getKey(); String variableName = entries.getValue().toLowerCase(); String putStatement = String.format("this.providers.put(\"%s\", %s);%n", fullFqn, variableName); builder.append(GeneratorUtils.TAB2).append(putStatement); } // close constructor builder.append(GeneratorUtils.TAB).append("}\n\n"); // generate getter builder.append(GeneratorUtils.TAB) .append("/** Returns the map with all the DtoFactoryVisitor Providers <FullClassFQN, Provider>. */\n"); builder.append(GeneratorUtils.TAB).append("public Map<String, Provider> getDtoFactoryVisitors()\n"); builder.append(GeneratorUtils.TAB).append("{\n"); builder.append(GeneratorUtils.TAB2).append("return providers;\n"); builder.append(GeneratorUtils.TAB).append("}\n"); // close class builder.append("}\n"); } }