001/* 002 * (C) Copyright 2006-2017 Nuxeo (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 * bstefanescu 018 */ 019package org.nuxeo.ecm.webengine.jaxrs; 020 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Set; 025 026import javax.ws.rs.core.Application; 027 028import org.osgi.framework.Bundle; 029 030/** 031 * A wrapper for a JAX-RS application fragment declared in manifest. The fragment application will be added to the 032 * target host application. 033 * 034 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 035 */ 036public class ApplicationFragment extends Application { 037 038 protected final String hostName; 039 040 protected final Bundle bundle; 041 042 protected final Map<String, String> attrs; 043 044 protected String appClass; 045 046 private volatile Application app; 047 048 public Application getApplication() { 049 return app; 050 } 051 052 public static Map<String, String> createAttributes(String hostName) { 053 Map<String, String> attrs = new HashMap<>(); 054 if (hostName != null) { 055 attrs.put("host", hostName); 056 } 057 return attrs; 058 } 059 060 public ApplicationFragment(Bundle bundle, String appClass) { 061 this(bundle, appClass, (String) null); 062 } 063 064 public ApplicationFragment(Bundle bundle, String appClass, String host) { 065 this(bundle, appClass, createAttributes(host)); 066 } 067 068 public ApplicationFragment(Bundle bundle, String appClass, Map<String, String> attrs) { 069 this.bundle = bundle; 070 this.appClass = appClass; 071 this.attrs = attrs; 072 String host = attrs.get("host"); 073 this.hostName = host == null ? "default" : host; 074 } 075 076 protected synchronized void createApp() { 077 try { 078 Object obj = bundle.loadClass(appClass).newInstance(); 079 if (obj instanceof ApplicationFactory) { 080 app = ((ApplicationFactory) obj).getApplication(bundle, attrs); 081 } else if (obj instanceof Application) { 082 app = (Application) obj; 083 } else { 084 throw new IllegalArgumentException("Expecting an Application or ApplicationFactory class: " + appClass); 085 } 086 } catch (ReflectiveOperationException | IOException e) { 087 String msg = "Cannot instantiate JAX-RS application " + appClass + " from bundle " 088 + bundle.getSymbolicName(); 089 throw new RuntimeException(msg, e); 090 } 091 } 092 093 public synchronized void reload() { 094 app = null; 095 } 096 097 public Bundle getBundle() { 098 return bundle; 099 } 100 101 public Map<String, String> getAttrs() { 102 return attrs; 103 } 104 105 public String getHostName() { 106 return hostName; 107 } 108 109 public Application get() { 110 if (app == null) { 111 createApp(); 112 } 113 return app; 114 } 115 116 @Override 117 public Set<Class<?>> getClasses() { 118 return get().getClasses(); 119 } 120 121 @Override 122 public Set<Object> getSingletons() { 123 return get().getSingletons(); 124 } 125 126}