/**
* <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.3 2008/02/28 07:08:24 mtaal Exp $
*/
package org.eclipse.emf.teneo.hibernate;
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
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 Method m = cls.getMethod("init");
// purposely passing null because it must be static
final EPackage 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) {
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;
}
}