001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Nuxeo - initial API and implementation 011 * 012 * $Id$ 013 */ 014 015package org.nuxeo.runtime.model.impl; 016 017import java.io.ByteArrayInputStream; 018import java.io.IOException; 019import java.io.InputStream; 020import java.net.URL; 021import java.util.Hashtable; 022import java.util.Iterator; 023import java.util.Map; 024 025import org.apache.commons.logging.Log; 026import org.apache.commons.logging.LogFactory; 027import org.nuxeo.common.utils.FileUtils; 028import org.nuxeo.runtime.RuntimeService; 029import org.nuxeo.runtime.RuntimeServiceException; 030import org.nuxeo.runtime.api.Framework; 031import org.nuxeo.runtime.model.ComponentManager; 032import org.nuxeo.runtime.model.ComponentName; 033import org.nuxeo.runtime.model.RegistrationInfo; 034import org.nuxeo.runtime.model.RuntimeContext; 035import org.nuxeo.runtime.model.StreamRef; 036import org.nuxeo.runtime.model.URLStreamRef; 037import org.nuxeo.runtime.osgi.OSGiRuntimeActivator; 038import org.nuxeo.runtime.osgi.OSGiRuntimeContext; 039import org.osgi.framework.Bundle; 040 041/** 042 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 043 */ 044public class DefaultRuntimeContext implements RuntimeContext { 045 046 private static final Log log = LogFactory.getLog(RuntimeContext.class); 047 048 private static final String UTF_8 = "UTF-8"; 049 050 protected RuntimeService runtime; 051 052 protected final ComponentDescriptorReader reader; 053 054 protected final Map<String, ComponentName> deployedFiles; 055 056 public DefaultRuntimeContext() { 057 this(Framework.getRuntime()); 058 } 059 060 public DefaultRuntimeContext(RuntimeService runtime) { 061 this.runtime = runtime; 062 reader = new ComponentDescriptorReader(); 063 deployedFiles = new Hashtable<String, ComponentName>(); 064 } 065 066 public void setRuntime(RuntimeService runtime) { 067 this.runtime = runtime; 068 } 069 070 @Override 071 public RuntimeService getRuntime() { 072 return runtime; 073 } 074 075 public Map<String, ComponentName> getDeployedFiles() { 076 return deployedFiles; 077 } 078 079 @Override 080 public URL getResource(String name) { 081 return Thread.currentThread().getContextClassLoader().getResource(name); 082 } 083 084 @Override 085 public URL getLocalResource(String name) { 086 return Thread.currentThread().getContextClassLoader().getResource(name); 087 } 088 089 @Override 090 public Class<?> loadClass(String className) throws ClassNotFoundException { 091 return Thread.currentThread().getContextClassLoader().loadClass(className); 092 } 093 094 @Override 095 public RegistrationInfo deploy(URL url) throws IOException { 096 return deploy(new URLStreamRef(url)); 097 } 098 099 @Override 100 public RegistrationInfo deploy(StreamRef ref) throws IOException { 101 String name = ref.getId(); 102 if (deployedFiles.containsKey(name)) { 103 return null; 104 } 105 RegistrationInfoImpl ri = createRegistrationInfo(ref); 106 if (ri == null || ri.name == null) { 107 // not parsed correctly, e.g., faces-config.xml 108 return null; 109 } 110 log.debug("Deploying component from url " + name); 111 ri.context = this; 112 ri.xmlFileUrl = ref.asURL(); 113 if (ri.getBundle() != null) { 114 // this is an external component XML. 115 // should use the real owner bundle as the context. 116 Bundle bundle = OSGiRuntimeActivator.getInstance().getBundle(ri.getBundle()); 117 if (bundle != null) { 118 ri.context = new OSGiRuntimeContext(bundle); 119 } 120 } 121 runtime.getComponentManager().register(ri); 122 deployedFiles.put(name, ri.getName()); 123 return ri; 124 } 125 126 @Override 127 public void undeploy(URL url) { 128 ComponentName name = deployedFiles.remove(url.toString()); 129 if (name == null) { 130 throw new IllegalArgumentException("not deployed " + url); 131 } 132 runtime.getComponentManager().unregister(name); 133 } 134 135 @Override 136 public void undeploy(StreamRef ref) { 137 ComponentName name = deployedFiles.remove(ref.getId()); 138 if (name == null) { 139 throw new IllegalArgumentException("not deployed " + ref); 140 } 141 runtime.getComponentManager().unregister(name); 142 } 143 144 @Override 145 public boolean isDeployed(URL url) { 146 return deployedFiles.containsKey(url.toString()); 147 } 148 149 @Override 150 public boolean isDeployed(StreamRef ref) { 151 return deployedFiles.containsKey(ref.getId()); 152 } 153 154 @Override 155 public RegistrationInfo deploy(String location) { 156 URL url = getLocalResource(location); 157 if (url == null) { 158 throw new IllegalArgumentException("No local resources was found with this name: " + location); 159 } 160 try { 161 return deploy(url); 162 } catch (IOException e) { 163 throw new RuntimeServiceException("Cannot deploy: " + location, e); 164 } 165 } 166 167 @Override 168 public void undeploy(String location) { 169 URL url = getLocalResource(location); 170 if (url == null) { 171 throw new IllegalArgumentException("No local resources was found with this name: " + location); 172 } 173 undeploy(url); 174 } 175 176 @Override 177 public boolean isDeployed(String location) { 178 URL url = getLocalResource(location); 179 if (url != null) { 180 return isDeployed(url); 181 } else { 182 log.warn("No local resources was found with this name: " + location); 183 return false; 184 } 185 } 186 187 @Override 188 public void destroy() { 189 Iterator<ComponentName> it = deployedFiles.values().iterator(); 190 ComponentManager mgr = runtime.getComponentManager(); 191 while (it.hasNext()) { 192 ComponentName name = it.next(); 193 it.remove(); 194 mgr.unregister(name); 195 } 196 } 197 198 @Override 199 public Bundle getBundle() { 200 return null; 201 } 202 203 public RegistrationInfoImpl createRegistrationInfo(StreamRef ref) throws IOException { 204 String source = FileUtils.read(ref.getStream()); 205 String expanded = Framework.expandVars(source); 206 try (InputStream in = new ByteArrayInputStream(expanded.getBytes(UTF_8))) { 207 return createRegistrationInfo(in); 208 } 209 } 210 211 public RegistrationInfoImpl createRegistrationInfo(InputStream in) throws IOException { 212 return reader.read(this, in); 213 } 214 215}