All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.plasma.provisioning.cli.ProvisioningTool Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
/**
 *         PlasmaSDO™ License
 * 
 * This is a community release of PlasmaSDO™, a dual-license 
 * Service Data Object (SDO) 2.1 implementation. 
 * This particular copy of the software is released under the 
 * version 2 of the GNU General Public License. PlasmaSDO™ was developed by 
 * TerraMeta Software, Inc.
 * 
 * Copyright (c) 2013, TerraMeta Software, Inc. All rights reserved.
 * 
 * General License information can be found below.
 * 
 * This distribution may include materials developed by third
 * parties. For license and attribution notices for these
 * materials, please refer to the documentation that accompanies
 * this distribution (see the "Licenses for Third-Party Components"
 * appendix) or view the online documentation at 
 * .
 *  
 */
package org.plasma.provisioning.cli;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.output.Format;
import org.modeldriven.fuml.Fuml;
import org.modeldriven.fuml.io.ResourceArtifact;
import org.plasma.common.bind.DefaultValidationEventHandler;
import org.plasma.config.Artifact;
import org.plasma.config.EnumSource;
import org.plasma.config.ImplementationProvisioning;
import org.plasma.config.InterfaceProvisioning;
import org.plasma.config.NamespaceProvisioning;
import org.plasma.config.PlasmaConfig;
import org.plasma.config.PropertyNameStyle;
import org.plasma.config.QueryDSLProvisioning;
import org.plasma.metamodel.Model;
import org.plasma.metamodel.Package;
import org.plasma.provisioning.AnnotationMetamodelAssembler;
import org.plasma.provisioning.MetamodelDataBinding;
import org.plasma.provisioning.adapter.ModelAdapter;
import org.plasma.provisioning.adapter.ProvisioningModel;
import org.plasma.provisioning.common.NamespaceUtils;
import org.plasma.xml.uml.MDModelAssembler;
import org.plasma.xml.uml.PapyrusModelAssembler;
import org.plasma.xml.uml.UMLModelAssembler;
import org.xml.sax.SAXException;

import joptsimple.BuiltinHelpFormatter;
import joptsimple.HelpFormatter;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpecBuilder;

public abstract class ProvisioningTool {
	private static Log log = LogFactory.getLog(ProvisioningTool.class);

	protected static void printUsage(OptionParser parser, Log theLog) throws IOException {
		HelpFormatter helpFormat = new BuiltinHelpFormatter(640, 1);
		parser.formatHelpWith(helpFormat);
		ByteArrayOutputStream helpOs = new ByteArrayOutputStream();
		parser.printHelpOn(helpOs);
		theLog.info("\n" + new String(helpOs.toByteArray()));
	}

	protected static Model validateStagingModel(File source) throws JAXBException, SAXException, IOException {
		FileInputStream is = new FileInputStream(source);
		MetamodelDataBinding binding = new MetamodelDataBinding(new DefaultValidationEventHandler());
		Model model = null;
		try {
			model = (Model) binding.validate(is);
		} finally {
			is.close();
		}

		ProvisioningModel validator = new ModelAdapter(model);

		return model;
	}

	protected static boolean regenerate(long lastExecution) {
		boolean stale = false;

		// check config file
		if (PlasmaConfig.getInstance().getConfigFileLastModifiedDate() > lastExecution) {
			stale = true;
			log.debug("detected stale configuration file '" + PlasmaConfig.getInstance().getConfigFileName()
					+ "' against time: " + String.valueOf(lastExecution));
		}

		if (!stale) {
			// check repo artifacts
			for (Artifact artifact : PlasmaConfig.getInstance().getRepository().getArtifacts()) {
				URL url = PlasmaConfig.class.getResource(artifact.getUrn());
				if (url == null)
					url = PlasmaConfig.class.getClassLoader().getResource(artifact.getUrn());
				log.debug("checking modified state of repository artifact '" + url.getFile() + "' against time: "
						+ String.valueOf(lastExecution));
				File urlFile = new File(url.getFile());
				if (urlFile.exists()) {
					if (urlFile.lastModified() > lastExecution) {
						stale = true;
						log.debug("detected stale repository artifact '" + url.getFile() + "' against time: "
								+ String.valueOf(lastExecution));
						break;
					}
				}
			}
		}

		// FIXME - how to determine if annotated classes have changed
		if (!stale) {
		}

		return stale;
	}

	/**
	 * Assembles provisioning meta model from annotated classes found using a class indexing utility, then loads
	 * convert the assembled model to UML, loading it into the FUML runtime.  
	 * @param annotationAssembler the meta model assembler
	 * @param destDir the destination dir
	 * @param options the provisioning options
	 * @param silentOpt the silent option  
	 */
	protected static void loadAnnotationModel(AnnotationMetamodelAssembler annotationAssembler, File destDir,
			OptionSet options, OptionSpecBuilder silentOpt) throws JAXBException, SAXException, IOException {

		if (log.isDebugEnabled()) {
			MetamodelDataBinding binding = new MetamodelDataBinding(new DefaultValidationEventHandler());
 			String xml = binding.marshal(annotationAssembler.getModel());
			File outFile = new File(destDir, "derived-technical-model.xml");
			FileOutputStream stream = new FileOutputStream(outFile);
			stream.write(xml.getBytes());
			stream.flush();
			stream.close();
			if (!options.has(silentOpt))
				log.debug("wrote derived model file to: " + outFile.getAbsoluteFile());
			// log.debug(xml);
		}
		ProvisioningModel annotationModelAdapter = 
				new ModelAdapter(annotationAssembler.getModel());
		
		if (configHasAllNamespaces(annotationModelAdapter.getLeafPackages()))
			return;

		String targetNamespaceUri = annotationModelAdapter.getModel().getUri();
		for (Package pkg : annotationModelAdapter.getLeafPackages()) {
			configureNamespace(pkg, targetNamespaceUri);
		}

		UMLModelAssembler umlAssembler = null;
		UMLPlatform platform = UMLPlatform.magicdraw;
		switch (platform) {
		case papyrus:
			umlAssembler = new PapyrusModelAssembler(annotationModelAdapter.getModel(), targetNamespaceUri, "tns");
			break;
		case magicdraw:
			umlAssembler = new MDModelAssembler(annotationModelAdapter.getModel(), targetNamespaceUri, "tns");
			break;
		}
		umlAssembler.setDerivePackageNamesFromURIs(false);
		String xmi = umlAssembler.getContent(Format.getPrettyFormat());
		if (log.isDebugEnabled()) {
			File xmiDebugFile = new File(destDir, annotationModelAdapter.getModel().getId() + ".uml");
			if (!options.has(silentOpt))
				log.debug("Writing UML/XMI to: " + xmiDebugFile.getAbsolutePath());
			try {
				FileOutputStream os = new FileOutputStream(xmiDebugFile);
				umlAssembler.getContent(os, Format.getPrettyFormat());
			} catch (FileNotFoundException e) {
			}
		}
		ByteArrayInputStream fumlStream = new ByteArrayInputStream(xmi.getBytes());

		if (log.isDebugEnabled())
			if (!options.has(silentOpt))
				log.debug("loading UML/XMI model");
		Fuml.load(new ResourceArtifact(targetNamespaceUri, targetNamespaceUri, fumlStream));

	}

	private static boolean configHasAllNamespaces(List packages) {
		boolean result = true;
		for (Package pkg : packages)
			if (!PlasmaConfig.getInstance().hasSDONamespace(pkg.getUri())) {
				result = false;
				break;
			}
		return result;
	}

	private static void configureNamespace(Package pkg, String targetNamespaceUri) {
		if (PlasmaConfig.getInstance().hasSDONamespace(pkg.getUri()))
			return; // skip if URI manually configured

		String pkgName = null;
		if (pkg.getNamespaceProvisioning() != null && pkg.getNamespaceProvisioning().getPackageName() != null
				&& pkg.getNamespaceProvisioning().getPackageName().trim().length() > 0) {
			pkgName = pkg.getNamespaceProvisioning().getPackageName().trim();
		} else {
			// derive a java package name from the namespace URI
			pkgName = NamespaceUtils.toPackageName(pkg.getUri());
		}

		// FIXME: while we may have class or even property level provisioning
		// info to store
		// based on annotated classes, there is nowhere to store it
		// in the config.
		NamespaceProvisioning nsProvConfig = new NamespaceProvisioning();
		nsProvConfig.setPackageName(pkgName);

		InterfaceProvisioning itfProv = new InterfaceProvisioning();
		nsProvConfig.setInterface(itfProv);
		// FIXME: collapse these elements into property name/value pairs
		itfProv.setPropertyNameStyle(PropertyNameStyle.ENUMS);
		itfProv.setEnumSource(EnumSource.EXTERNAL);

		ImplementationProvisioning implProv = new ImplementationProvisioning();
		nsProvConfig.setImplementation(implProv);

		QueryDSLProvisioning queryDSL = new QueryDSLProvisioning();
		nsProvConfig.setQueryDSL(queryDSL);
		queryDSL.setGenerate(true);

		PlasmaConfig.getInstance().addDynamicSDONamespace(pkg.getUri(), targetNamespaceUri, nsProvConfig);
	}

	protected static void writeContent(InputStream is, OutputStream os) throws IOException {
		byte[] buf = new byte[4000];
		int len = -1;
		try {
			while ((len = is.read(buf)) != -1)
				os.write(buf, 0, len);
		} finally {
			is.close();
			os.flush();
		}
	}

	public static byte[] readContent(InputStream is) throws IOException {
		byte[] result;
		byte[] buf = new byte[4000];
		ByteArrayOutputStream os = new ByteArrayOutputStream(buf.length);
		int len = -1;
		try {
			while ((len = is.read(buf, 0, buf.length)) != -1)
				os.write(buf, 0, len);
			result = os.toByteArray();
		} finally {
			is.close();
			os.flush();
			os.close();
		}
		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy