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