org.eclipse.emf.teneo.hibernate.EPackageConstructor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.teneo.hibernate.EPackageConstructor.java

Source

/**
 * <copyright>
 *
 * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others
 * 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:
 *   Martin Taal
 * </copyright>
 *
 * $Id: EPackageConstructor.java,v 1.5 2010/02/06 18:25:50 mtaal Exp $
 */

package org.eclipse.emf.teneo.hibernate;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;

/**
 * Reads epackages from different formats and makes them available to other beans.
 * 
 * @author <a href="mtaal@elver.org">Martin Taal</a>
 */
public class EPackageConstructor {

    // The logger
    private static final Log log = LogFactory.getLog(EPackageConstructor.class);

    // The ecore context in which this app runs
    // private EcoreContext ecoreContext;

    // The arraylist of epackages, is build in the getEPackages call
    private List<EPackage> ePackages = null;

    // The classnames of EcoreModelClasses
    private List<String> ecoreModelClasses = new ArrayList<String>();

    // The array of model class names
    private List<String> ecoreModelFiles = new ArrayList<String>();

    private boolean initialized = false;

    /**
     * The list of files with ecore or xsd models.
     */
    public void setModelFiles(List<String> ecoreModelFiles) {
        this.ecoreModelFiles = ecoreModelFiles;
    }

    /**
     * Set the list of EcoreModelPackages which are to be read.
     */
    public void setModelClasses(List<String> ecoreModelClasses) {
        this.ecoreModelClasses = ecoreModelClasses;
    }

    /**
     * This method will read the models from the modelFiles and the EcoreModelPackages. The EPackages are initialized
     * and registered in the EPackage registry.
     * 
     * @return the EPackages which are read from the modelFiles or are defined in EcoreModelPackages.
     */
    public List<EPackage> getEPackages() {
        if (ePackages == null) {
            initialize();
        }
        return ePackages;
    }

    /** Initialize it all */
    private void initialize() {
        if (initialized) {
            return;
        }
        // build the list of EPackages
        if (log.isDebugEnabled()) {
            log.debug("Reading EPackages");
        }
        final ArrayList<EPackage> ePacks = new ArrayList<EPackage>();
        ePacks.addAll(buildFromModelClasses());
        ePacks.addAll(buildFromModelFiles());

        for (EPackage epackage : ePacks) {
            log.info("Registered EPackage: " + epackage.getNsURI());
        }

        // also add subpackages
        for (EPackage ePackage : new ArrayList<EPackage>(ePacks)) {
            addSubPackages(ePacks, ePackage);
        }

        ePackages = ePacks;
        initialized = true;
    }

    private void addSubPackages(List<EPackage> list, EPackage ePackage) {
        for (EPackage subPackage : ePackage.getESubpackages()) {
            if (!list.contains(subPackage)) {
                list.add(subPackage);
                addSubPackages(list, subPackage);
            }
        }
    }

    /**
     * Build a list of EPackages from the passed EcoreModelClasses.
     */
    private List<EPackage> buildFromModelClasses() {
        final ArrayList<EPackage> result = new ArrayList<EPackage>();
        for (String ecoreModelPackageClassName : ecoreModelClasses) {
            try {
                final Class<?> cls = this.getClass().getClassLoader().loadClass(ecoreModelPackageClassName);
                final EPackage emp;
                // handle the case that this is an EPackage interface
                if (cls.isInterface()) {
                    final Field f = cls.getField("eINSTANCE");
                    // purposely passing null because it must be static
                    emp = (EPackage) f.get(null);
                } else {
                    final Method m = cls.getMethod("init");
                    // purposely passing null because it must be static
                    emp = (EPackage) m.invoke(null);
                }

                // initialise the emp, will also read the epackage
                result.add(emp);
            } catch (Exception e) {
                throw new IllegalStateException(
                        "Excption while trying to retrieve EcoreModelPackage instance from class: "
                                + ecoreModelPackageClassName,
                        e);
            }
        }
        return result;
    }

    /**
     * Builds a list of epackages from the modelfiles, pre-normalized for duplicates and not registered.
     */
    private List<EPackage> buildFromModelFiles() {
        // separate the files in xsd and ecore files and treat each of them separately
        final ArrayList<String> ecoreFiles = new ArrayList<String>();
        final ArrayList<String> xsdFiles = new ArrayList<String>();
        for (String modelFile : ecoreModelFiles) {
            if (modelFile.endsWith(".xsd")) {
                xsdFiles.add(modelFile.trim());
            } else {
                if (!modelFile.trim().endsWith(".ecore")) {
                    log.warn("Filename " + modelFile + " passed as modelFile but it does not end on either "
                            + "xsd or ecore, processing it anyway.");
                }
                ecoreFiles.add(modelFile.trim());
            }
        }

        // now get the ecores and xsd's parse them separately
        final ArrayList<EPackage> result = new ArrayList<EPackage>();
        result.addAll(readFromEcore(ecoreFiles));
        // result.addAll(readFromXmlSchema(xsdFiles));

        return result;
    }

    // /**
    // * Builds and registers EPackages from an XML Schema.
    // *
    // * @param file
    // * The XML Schema file.
    // */
    // private List<EPackage> readFromXmlSchema(List<String> xsdFiles) {
    // final ArrayList<EPackage> result = new ArrayList<EPackage>();
    // for (String xsdFile : xsdFiles) {
    // log.debug("Building ECore model from XML Schema \"" + xsdFile + "\".");
    // try {
    // // final String path = ecoreContext.getQualifiedPath(xsdFile);
    // final java.net.URI netURI = this.getClass().getResource(xsdFile).toURI();
    // final URI uri = URI.createURI(netURI.toString());
    //
    // // Note: we use an inline SerializableXSDEcoreBuilder to avoid a dependency on
    // // XSDEcoreBuilder during
    // // classloading.
    // for (Object obj : new XSDEcoreBuilder().generate(uri)) {
    // final EPackage ePackage = (EPackage) obj;
    // result.add(ePackage);
    // }
    // } catch (Exception e) {
    // throw new StateException("Could not build ECore model from XML Schema, from file " + xsdFile, e);
    // }
    // }
    // return result;
    // }

    /**
     * Reads the epackages present in the passed ecore files. Note this method does not register the epackages. It does
     * not check for duplicates either.
     */
    private List<EPackage> readFromEcore(List<String> ecoreFiles) {
        final ResourceSet resourceSet = new ResourceSetImpl();
        resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*",
                new EcoreResourceFactoryImpl());
        final ArrayList<EPackage> epackages = new ArrayList<EPackage>();
        for (String ecoreFile : ecoreFiles) {
            if (log.isDebugEnabled()) {
                log.debug("Reading ecore file: " + ecoreFile);
            }
            // final String path = ecoreContext.getQualifiedPath(ecoreFile);
            // log.debug("Using qualified path: " + path);
            try {
                final java.net.URI netURI = this.getClass().getResource(ecoreFile).toURI();
                final Resource res = resourceSet.getResource(URI.createURI(netURI.toString()), true);
                for (Object obj : res.getContents()) {
                    if (obj instanceof EPackage) {
                        epackages.add((EPackage) obj);
                    }
                }
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
        return epackages;
    }
}