/******************************************************************************* * Copyright © 2012, 2013 IBM Corporation 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: * IBM Corporation - initial API and implementation * *******************************************************************************/ package resources.edt.binding; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import org.eclipse.edt.javart.Constants; import org.eclipse.edt.javart.Executable; import org.eclipse.edt.javart.Runtime; import org.eclipse.edt.javart.messages.Message; import org.eclipse.edt.javart.resources.egldd.Binding; import org.eclipse.edt.javart.resources.egldd.RuntimeDeploymentDesc; import eglx.java.JavaObjectException; import eglx.lang.AnyException; import eglx.lang.DynamicAccessException; import eglx.lang.Resources.ResourceLocator; import eglx.lang.SysLib; public class BindingResourceProcessor { protected static Map<QName, Binding> bindings = new HashMap<QName, Binding>(); protected ResourceLocator resourceLocator; public BindingResourceProcessor() { resourceLocator = new RuntimeResourceLocator(); } public Object resolve(URI uri) throws AnyException{ URI dd = null; String name; if(uri.getFragment() == null){ dd = getDefaultDDURI(); name = uri.getSchemeSpecificPart(); } else{ try { dd = new URI(uri.getSchemeSpecificPart()); } catch (URISyntaxException e) { JavaObjectException jox = new JavaObjectException(); jox.exceptionType = URI.class.getName(); jox.initCause( e ); throw jox.fillInMessage( Message.RESOURCE_URI_EXCEPTION, uri ); } name = uri.getFragment(); } Binding binding = getBinding(name, dd, resourceLocator); if(binding != null && binding.getType() != null){ return getResource(binding, dd); } else{ DynamicAccessException dax = new DynamicAccessException(); dax.key = name; throw dax.fillInMessage( Message.ERROR_RESOURCE_BINDING_NOT_FOUND,name, dd ); } } protected Object getResource(Binding binding, URI dd) throws AnyException{ String factoryName; String factoryPackage; int idx = binding.getType().lastIndexOf('.'); if(idx > -1){ factoryName = binding.getType().substring(idx+1); factoryPackage = binding.getType().substring(0,idx+1); } else{ factoryName = binding.getType(); factoryPackage = ""; } factoryName = new StringBuffer(factoryName).replace(0, 1, String.valueOf(factoryName.charAt(0)).toUpperCase()).toString() + "Factory"; String implFactory = "resources." + factoryPackage + factoryName; BindingFactory factory = null; try { Class<?> clazz = Runtime.getRunUnit().getClass().getClassLoader().loadClass(implFactory); factory = (BindingFactory)clazz.newInstance(); } catch (Exception e) { DynamicAccessException dax = new DynamicAccessException(); dax.key = binding.getName(); dax.initCause( e ); throw dax.fillInMessage( Message.ERROR_RESOURCE_FACTORY_NOT_FOUND, binding.getName(), binding.getType(), dd ); } try { Object resource = factory.createResource(binding); if(resource == null){ DynamicAccessException dax = new DynamicAccessException(); dax.key = binding.getName(); throw dax.fillInMessage( Message.ERROR_NO_RESOURCE_IMPLEMENTATION, binding.getName(), binding.getType(), dd ); } return resource; } catch (Exception e) { DynamicAccessException dax = new DynamicAccessException(); dax.key = binding.getName(); dax.initCause( e ); throw dax.fillInMessage( Message.ERROR_RESOURCE_IMPLEMENTATION_EXCEPTION, binding.getName(), binding.getType(), dd ); } } protected URI getDefaultDDURI() throws AnyException { Executable app = Runtime.getRunUnit().getActiveExecutable(); String dd = null; if (app != null) { dd = SysLib.getProperty(Constants.APPLICATION_PROPERTY_FILE_NAME_KEY + "." + app.getClass().getCanonicalName()); } if (dd == null) { dd = SysLib.getProperty(Constants.APPLICATION_PROPERTY_FILE_NAME_KEY); } if (dd == null || dd.isEmpty()) { AnyException ae = new AnyException(); throw ae.fillInMessage( Message.MISSING_DEFAULT_DD ); } try { return createFileURI(dd); } catch (URISyntaxException e) { } return null; } protected URI createFileURI(String fileName) throws URISyntaxException{ return new URI("file:" + fileName); } protected Binding getBinding(String bindingURI, URI propertyFileURI, ResourceLocator resourceLocator) { QName resourceId = new QName(propertyFileURI.toASCIIString(), bindingURI); Binding binding = bindings.get(resourceId); if(binding == null){ RuntimeDeploymentDesc dd = getDeploymentDesc(propertyFileURI, resourceLocator); binding = getBinding(bindingURI, dd); if(binding == null){ Set<String> seenDDs = new HashSet<String>(); seenDDs.add(dd.getName()); binding = getBinding(bindingURI, dd.getIncludedDescs(), resourceLocator, seenDDs); } if(binding != null){ bindings.put(resourceId, binding); } } return binding; } protected RuntimeDeploymentDesc getDeploymentDesc(URI propertyFileURI, ResourceLocator resourceLocator){ return resourceLocator.getDeploymentDesc(propertyFileURI); } protected Binding getBinding(String name, List<String> includes, ResourceLocator resourceLocator, Set<String> seenDDs)throws AnyException{ List<RuntimeDeploymentDesc> includedDDs = new ArrayList<RuntimeDeploymentDesc>(); Binding binding = null; for(String ddName : includes){ if (seenDDs.contains(ddName)) { continue; } seenDDs.add(ddName); RuntimeDeploymentDesc includedDD; try { includedDD = getDeploymentDesc(createFileURI(ddName), resourceLocator); binding = getBinding(name, includedDD); if(binding != null){ break; } else{ includedDDs.add(includedDD); } } catch (URISyntaxException e) { JavaObjectException jox = new JavaObjectException(); jox.exceptionType = URI.class.getName(); jox.initCause( e ); throw jox.fillInMessage( Message.RESOURCE_URI_EXCEPTION, ddName ); } } if (binding == null) { for(RuntimeDeploymentDesc includedDD : includedDDs){ binding = getBinding(name, includedDD.getIncludedDescs(), resourceLocator, seenDDs); if(binding != null){ break; } } } return binding; } protected Binding getBinding(String name, RuntimeDeploymentDesc dd){ for(Binding binding : dd.getBindings()){ if(name.equalsIgnoreCase(binding.getName())){ return binding; } } return null; } public static Map<QName, Binding> getBindings() { return bindings; } }