blob: 33c43af1e237fcf3d8216b5345e337945b204777 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 BREDEX GmbH.
* 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:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.toolkit.api.gen.internal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jubula.toolkit.api.gen.ActionHandlerGenerator;
import org.eclipse.jubula.toolkit.api.gen.ComponentClassGenerator;
import org.eclipse.jubula.toolkit.api.gen.FactoryGenerator;
import org.eclipse.jubula.toolkit.api.gen.ToolkitInfoGenerator;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.CommonGenInfo;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.CompInfoForFactoryGen;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.CompInfoForToolkitGen;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.ComponentGenInfo;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.FactoryGenInfo;
import org.eclipse.jubula.toolkit.api.gen.internal.genmodel.ToolkitGenInfo;
import org.eclipse.jubula.toolkit.api.gen.internal.utils.ConfigLoader;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.utils.generator.CompSystemProcessor;
import org.eclipse.jubula.tools.internal.utils.generator.ComponentInfo;
import org.eclipse.jubula.tools.internal.utils.generator.ToolkitConfig;
import org.eclipse.jubula.tools.internal.utils.generator.ToolkitInfo;
import org.eclipse.jubula.tools.internal.xml.businessmodell.CompSystem;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Component;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ComponentClass;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ConcreteComponent;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ToolkitDescriptor;
/**
* Generates classes for components from comp system
*/
public class APIGenerator {
/** class generator */
private static ComponentClassGenerator componentClassGenerator =
new ComponentClassGenerator();
/** action handler class generator */
private static ActionHandlerGenerator actionHandlerGenerator =
new ActionHandlerGenerator();
/** factory generator */
private static FactoryGenerator factoryGenerator =
new FactoryGenerator();
/** factory generator */
private static ToolkitInfoGenerator toolkitInfoGenerator =
new ToolkitInfoGenerator();
/** containing information for factory generation.
* will be reseted for each toolkit */
private static FactoryGenInfo factoryGenInfo;
/** containing information for toolkit information generation.
* will be reseted for each toolkit */
private static ToolkitGenInfo tookitGenInfo;
/** whether a class containing information about a toolkit needs to be generated */
private static boolean toolkitNeedsInfoClass = false;
/**
* map containing component name mappings
* will be reseted for each component
*/
private static Map<String, String> compNameMap =
new TreeMap<String, String>();
/**
* Constructor
*/
private APIGenerator() {
// hidden
}
/**
* main
* @param args args
*/
public static void main(String[] args) {
ConfigLoader loader = ConfigLoader.getInstance();
String generationBaseDir = loader.getGenerationDir();
ToolkitConfig config = loader.getToolkitConfig();
CompSystemProcessor processor = new CompSystemProcessor(config);
List<ToolkitInfo> toolkitInfos = processor.getToolkitInfos();
String converterInfoDir = loader.getConverterInfoDir();
// Clean up
File converterDirectory = new File(converterInfoDir);
if (converterDirectory.exists()) {
try {
FileUtils.cleanDirectory(converterDirectory);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
} else {
converterDirectory.mkdirs();
}
for (ToolkitInfo tkInfo : toolkitInfos) {
cleanUp(tkInfo, generationBaseDir);
}
// Generate classes and interfaces toolkit by toolkit
for (ToolkitInfo tkInfo : toolkitInfos) {
factoryGenInfo = new FactoryGenInfo();
tookitGenInfo = new ToolkitGenInfo();
toolkitNeedsInfoClass = false;
List<ComponentInfo> compInfos = processor.getCompInfos(
tkInfo.getType(), tkInfo.getShortType());
for (ComponentInfo compInfo : compInfos) {
compNameMap.clear();
Component component = compInfo.getComponent();
// generate interface
createClass(component, generationBaseDir, true);
//generate implementation class
createClass(component, generationBaseDir, false);
createComponentNameInfoFile(component, compNameMap,
converterInfoDir);
}
// Generate a component factory and an information class for each toolkit
CompSystem compSystem = processor.getCompSystem();
ToolkitDescriptor toolkitDesriptor = compSystem
.getToolkitDescriptor(tkInfo.getType());
CommonGenInfo genInfoForFactory =
new CommonGenInfo(toolkitDesriptor, false);
if (toolkitNeedsInfoClass) {
CommonGenInfo genInfoForToolkit =
new CommonGenInfo(toolkitDesriptor, true);
createToolkitInfo(genInfoForToolkit, generationBaseDir);
factoryGenInfo.setToolkitInfoName(
genInfoForToolkit.getToolkitName(),
genInfoForToolkit.getFqClassName());
}
createFactory(genInfoForFactory, generationBaseDir);
}
}
/**
* Creates the info file for a component for the converter
* @param component the component
* @param map name info map
* @param dirPath path where to put info file
*/
private static void createComponentNameInfoFile(Component component,
Map<String, String> map, String dirPath) {
StringBuffer content = new StringBuffer();
for (String key : map.keySet()) {
content.append(key + StringConstants.EQUALS_SIGN
+ map.get(key) + "\n"); //$NON-NLS-1$
}
File dir = new File(dirPath);
File file = new File(dirPath + StringConstants.SLASH
+ component.getType() + ".properties"); //$NON-NLS-1$
createFile(dir, file, content.toString());
}
/**
* Deletes all generated content of a given toolkit
* @param tkInfo the toolkit
* @param generationBaseDirTemplate location of generated content
*/
private static void cleanUp(ToolkitInfo tkInfo,
String generationBaseDirTemplate) {
String name = tkInfo.getShortType().toLowerCase()
.replace("abstract", "base"); //$NON-NLS-1$ //$NON-NLS-2$
String generationBaseDir = MessageFormat.format(
generationBaseDirTemplate,
new Object[] {name});
File dir = new File(generationBaseDir);
emptyDirectory(dir);
}
/**
* Empties a directory recursively
* @param dir the directory
*/
private static void emptyDirectory(File dir) {
if (dir.exists()) {
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
try {
FileUtils.deleteDirectory(file);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
}
}
}
/**
* creates class for component
* @param component the component
* @param generationBaseDirTemplate directory for generation
* @param generateInterface whether an interface should be generated
*/
private static void createClass(Component component,
String generationBaseDirTemplate, Boolean generateInterface) {
CommonGenInfo genInfo = new CommonGenInfo(component);
ComponentGenInfo compInfo = new ComponentGenInfo(component,
generateInterface, genInfo.getToolkitPackageName(),
genInfo.getClassName(), compNameMap);
genInfo.setSpecificInformation(compInfo);
String path = StringConstants.EMPTY;
if (generateInterface) {
path = compInfo.getInterfaceDirectoryPath();
} else {
path = genInfo.getClassDirectoryPath();
}
String className = genInfo.getClassName();
String generationBaseDir = MessageFormat.format(
generationBaseDirTemplate,
new Object[] {genInfo.getToolkitPackageName()});
File dir = new File(generationBaseDir + path);
File file = new File(dir, className + ".java"); //$NON-NLS-1$
String content = componentClassGenerator.generate(genInfo);
createFile(dir, file, content);
dir = new File(generationBaseDir + path + "/handler"); //$NON-NLS-1$
file = new File(dir, className + "ActionHandler.java"); //$NON-NLS-1$
content = actionHandlerGenerator.generate(genInfo);
createFile(dir, file, content);
/* After generating an impl class, add component information
* to factory and toolkit generation information */
if (!generateInterface) {
ComponentClass componentClass = null;
String testerClass = null;
if (component instanceof ConcreteComponent) {
ConcreteComponent concreteComponent =
(ConcreteComponent) component;
componentClass = concreteComponent.getComponentClass();
testerClass = concreteComponent.getTesterClass();
if (componentClass != null && testerClass != null) {
toolkitNeedsInfoClass = true;
}
}
if (!compInfo.hasDefaultMapping()
|| (componentClass != null
&& !componentClass.getName().isEmpty())) {
CompInfoForFactoryGen compInfoForFactory =
new CompInfoForFactoryGen(
genInfo.getClassName(),
genInfo.getClassPackageName(),
componentClass,
compInfo.hasDefaultMapping(),
compInfo.getMostSpecificVisibleSuperTypeName());
String sinceC = component.getSince();
if (StringUtils.isNotBlank(sinceC)) {
compInfoForFactory.setSince(sinceC);
}
factoryGenInfo.addCompInformation(compInfoForFactory);
}
tookitGenInfo.addCompInformation(new CompInfoForToolkitGen(
componentClass, testerClass));
}
}
/**
* creates factory for toolkit
* @param tkGenInfo the generation information for the toolkit
* @param generationBaseDirTemplate directory for generation
*/
private static void createFactory(CommonGenInfo tkGenInfo,
String generationBaseDirTemplate) {
tkGenInfo.setSpecificInformation(factoryGenInfo);
String path = tkGenInfo.getClassDirectoryPath();
String className = tkGenInfo.getClassName();
String generationBaseDir = MessageFormat.format(
generationBaseDirTemplate,
new Object[] {tkGenInfo.getToolkitPackageName()});
File dir = new File(generationBaseDir + path);
File file = new File(dir, className + ".java"); //$NON-NLS-1$
String content = factoryGenerator.generate(tkGenInfo);
createFile(dir, file, content);
}
/**
* creates toolkit information class
* @param tkGenInfo the generation information for the toolkit
* @param generationBaseDirTemplate directory for generation
*/
private static void createToolkitInfo(CommonGenInfo tkGenInfo,
String generationBaseDirTemplate) {
tkGenInfo.setSpecificInformation(tookitGenInfo);
String path = tkGenInfo.getClassDirectoryPath();
String className = tkGenInfo.getClassName();
String generationBaseDir = MessageFormat.format(
generationBaseDirTemplate,
new Object[] {tkGenInfo.getToolkitPackageName()});
File dir = new File(generationBaseDir + path);
File file = new File(dir, className + ".java"); //$NON-NLS-1$
String content = toolkitInfoGenerator.generate(tkGenInfo);
createFile(dir, file, content);
}
/** creates a file with given content in a given directory
* @param dir the directory
* @param file the file
* @param content the content
*/
private static void createFile(File dir, File file, String content) {
if (!file.exists()) {
try {
dir.mkdirs();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
try (FileOutputStream fop = new FileOutputStream(file)) {
byte[] contentInBytes = content.getBytes();
IOUtils.write(contentInBytes, fop);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
} else {
System.out.println("ERROR: " + file.getName() + " already exists!"); //$NON-NLS-1$ //$NON-NLS-2$
System.exit(1);
}
}
}