Java tutorial
/******************************************************************************* * Copyright (c) 2010 itemis AG (http://www.itemis.eu) 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 *******************************************************************************/ package org.eclipse.xtext.mwe; import java.io.File; import java.util.Collection; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.mwe.core.WorkflowContext; import org.eclipse.emf.mwe.core.WorkflowInterruptedException; import org.eclipse.emf.mwe.core.issues.Issues; import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; import org.eclipse.xtext.ISetup; import org.eclipse.xtext.resource.IResourceServiceProvider; import org.eclipse.xtext.resource.containers.DelegatingIAllContainerAdapter; import org.eclipse.xtext.resource.containers.IAllContainersState; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; /** * <p> * A Reader used to read EMF resources from a set of pathes. * A path can point to a folder or an archive (zips and jars are supported). * Those pathes are recursively scanned and all resources for which an {@link IResourceServiceProvider} is * registered in the {@link org.eclipse.xtext.resource.IResourceServiceProvider.Registry} will be available. * </p> * * <p> * The {@link ISetup} of an Xtext language registers such an {@link IResourceServiceProvider} automatically. If you want to integrate with non Xtext-based models, * make sure to add {@link IResourceServiceProvider} manually. The easiest way might be to implement an {@link ISetup}. * </p> * <p> * A {@link SlotEntry} is responsible for selecting certain EObjects from the loaded resources. * It supports selecting EObjects by their name (see {@link org.eclipse.xtext.resource.IEObjectDescription}) or by an EClass. * In many cases such selction returns multiple EObjects, if you're only interested in one element set the <code>firstOnly</code> flag to <code>true</code>. * </p> * <p> * You might want to populate multiple workflow slots with model elements. * </p> * <p> * Below an example of a usage in the MWE XML syntax: * </p> * <pre> * <component class="org.eclipse.xtext.mwe.Reader" useJavaClassPath="true"> * <register class="foo.bar.MyLanguageSetandaloneSetup"/> * <load slot="types" type="Type"/> * <validate/> * </component> * </pre> * It supports fetching elements by type * {@link IResourceServiceProvider#getResourceDescriptionManager()} is used to identify model elements within these resources. * * @author Sven Efftinge - Initial contribution and API */ public class Reader extends AbstractReader { protected final static Logger log = Logger.getLogger(Reader.class.getName()); protected List<String> pathes = Lists.newArrayList(); /** * <p> * A comma-separated list of paths pointing to a folder, jar or zip which contains EMF resources. * </p> * <p> * Example use (MWE2): * </p> * <code> * path = "./foo/bar.jar,./src/main/model" * </code> * <p> * Example use (MWE1): * </p> * <code> * <path value="./foo/bar.jar,./src/main/model"/> * </code> */ public void addPath(String path) { for (String p : path.split(",")) { this.pathes.add(p.trim()); } } public List<String> getPathes() { return pathes; } /** * <p> * Automatically adds all class path entries of the current process (more specifically uses 'java.class.path' system property). * </p> * <p> * Example use (MWE2): * </p> * <code> * useJavaClassPath = true * </code> * <p> * Example use (MWE1): * </p> * <code> * <useJavaClassPath value="true"/> * </code> */ public void setUseJavaClassPath(boolean isUse) { if (isUse) { String classPath = System.getProperty("java.class.path"); String separator = System.getProperty("path.separator"); String[] strings = classPath.split(separator); for (String path : strings) { addPath(path); } } } private UriFilter filter; /** * Optionally set a filter that specifies which URIs are valid to be read. * A common use-case for filters is a file-name based selection of valid * URIs. */ public void setUriFilter(UriFilter filter) { this.filter = filter; } public UriFilter getUriFilter() { return filter; } private ContainersStateFactory containersStateFactory = new ContainersStateFactory(); public void setContainersStateFactory(ContainersStateFactory containersStateFactory) { this.containersStateFactory = containersStateFactory; } public ContainersStateFactory getContainersStateFactory() { return containersStateFactory; } @Override protected void checkConfigurationInternal(Issues issues) { super.checkConfigurationInternal(issues); if (pathes.isEmpty()) { issues.addWarning("No path set, using java class path entries (useJavaClassPath='true')."); setUseJavaClassPath(true); } if (log.isDebugEnabled()) { log.debug("Resource Pathes : " + pathes); } for (String path : pathes) { if (!new File(path).exists()) issues.addWarning("Skipping the path '" + path + "', because it does not exist."); } } @Override protected void invokeInternal(WorkflowContext ctx, ProgressMonitor monitor, Issues issues) { ResourceSet resourceSet = getResourceSet(); Multimap<String, URI> uris = getPathTraverser().resolvePathes(pathes, new Predicate<URI>() { @Override public boolean apply(URI input) { boolean result = true; if (getUriFilter() != null) result = getUriFilter().matches(input); if (result) result = getRegistry().getResourceServiceProvider(input) != null; return result; } }); IAllContainersState containersState = containersStateFactory.getContainersState(pathes, uris); installAsAdapter(resourceSet, containersState); populateResourceSet(resourceSet, uris); getValidator().validate(resourceSet, getRegistry(), issues); addModelElementsToContext(ctx, resourceSet); } protected PathTraverser getPathTraverser() { return new PathTraverser(); } protected void populateResourceSet(ResourceSet set, Multimap<String, URI> uris) { Collection<URI> values = Sets.newHashSet(uris.values()); for (URI uri : values) { set.createResource(uri); } } protected void installAsAdapter(ResourceSet set, IAllContainersState containersState) throws WorkflowInterruptedException { set.eAdapters().add(new DelegatingIAllContainerAdapter(containersState)); } }