View Javadoc
1   package org.argeo.cms.internal.kernel;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.PrintStream;
6   import java.net.URI;
7   import java.net.URISyntaxException;
8   import java.net.URL;
9   import java.nio.file.Path;
10  import java.nio.file.Paths;
11  import java.security.PrivilegedAction;
12  import java.security.URIParameter;
13  import java.util.Dictionary;
14  import java.util.Hashtable;
15  import java.util.Properties;
16  import java.util.TreeMap;
17  import java.util.TreeSet;
18  
19  import javax.jcr.Repository;
20  import javax.jcr.RepositoryException;
21  import javax.jcr.Session;
22  import javax.security.auth.Subject;
23  import javax.security.auth.login.LoginContext;
24  import javax.security.auth.login.LoginException;
25  
26  import org.apache.commons.logging.Log;
27  import org.argeo.api.DataModelNamespace;
28  import org.argeo.api.NodeConstants;
29  import org.argeo.cms.CmsException;
30  import org.osgi.framework.Bundle;
31  import org.osgi.framework.BundleContext;
32  import org.osgi.framework.FrameworkUtil;
33  import org.osgi.util.tracker.ServiceTracker;
34  
35  /** Package utilities */
36  class KernelUtils implements KernelConstants {
37  	final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
38  	final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
39  
40  	static void setJaasConfiguration(URL jaasConfigurationUrl) {
41  		try {
42  			URIParameter uriParameter = new URIParameter(jaasConfigurationUrl.toURI());
43  			javax.security.auth.login.Configuration jaasConfiguration = javax.security.auth.login.Configuration
44  					.getInstance("JavaLoginConfig", uriParameter);
45  			javax.security.auth.login.Configuration.setConfiguration(jaasConfiguration);
46  		} catch (Exception e) {
47  			throw new CmsException("Cannot set configuration " + jaasConfigurationUrl, e);
48  		}
49  	}
50  
51  	static Dictionary<String, ?> asDictionary(Properties props) {
52  		Hashtable<String, Object> hashtable = new Hashtable<String, Object>();
53  		for (Object key : props.keySet()) {
54  			hashtable.put(key.toString(), props.get(key));
55  		}
56  		return hashtable;
57  	}
58  
59  	static Dictionary<String, ?> asDictionary(ClassLoader cl, String resource) {
60  		Properties props = new Properties();
61  		try {
62  			props.load(cl.getResourceAsStream(resource));
63  		} catch (IOException e) {
64  			throw new CmsException("Cannot load " + resource + " from classpath", e);
65  		}
66  		return asDictionary(props);
67  	}
68  
69  	static File getExecutionDir(String relativePath) {
70  		File executionDir = new File(getFrameworkProp("user.dir"));
71  		if (relativePath == null)
72  			return executionDir;
73  		try {
74  			return new File(executionDir, relativePath).getCanonicalFile();
75  		} catch (IOException e) {
76  			throw new CmsException("Cannot get canonical file", e);
77  		}
78  	}
79  
80  	static File getOsgiInstanceDir() {
81  		return new File(getBundleContext().getProperty(OSGI_INSTANCE_AREA).substring("file:".length()))
82  				.getAbsoluteFile();
83  	}
84  
85  	static Path getOsgiInstancePath(String relativePath) {
86  		return Paths.get(getOsgiInstanceUri(relativePath));
87  	}
88  
89  	static URI getOsgiInstanceUri(String relativePath) {
90  		String osgiInstanceBaseUri = getFrameworkProp(OSGI_INSTANCE_AREA);
91  		return safeUri(osgiInstanceBaseUri + (relativePath != null ? relativePath : ""));
92  	}
93  
94  	static File getOsgiConfigurationFile(String relativePath) {
95  		try {
96  			return new File(new URI(getBundleContext().getProperty(OSGI_CONFIGURATION_AREA) + relativePath))
97  					.getCanonicalFile();
98  		} catch (Exception e) {
99  			throw new CmsException("Cannot get configuration file for " + relativePath, e);
100 		}
101 	}
102 
103 	static String getFrameworkProp(String key, String def) {
104 		String value = getBundleContext().getProperty(key);
105 		if (value == null)
106 			return def;
107 		return value;
108 	}
109 
110 	static String getFrameworkProp(String key) {
111 		return getFrameworkProp(key, null);
112 	}
113 
114 	// Security
115 	// static Subject anonymousLogin() {
116 	// Subject subject = new Subject();
117 	// LoginContext lc;
118 	// try {
119 	// lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject);
120 	// lc.login();
121 	// return subject;
122 	// } catch (LoginException e) {
123 	// throw new CmsException("Cannot login as anonymous", e);
124 	// }
125 	// }
126 
127 	static void logFrameworkProperties(Log log) {
128 		BundleContext bc = getBundleContext();
129 		for (Object sysProp : new TreeSet<Object>(System.getProperties().keySet())) {
130 			log.debug(sysProp + "=" + bc.getProperty(sysProp.toString()));
131 		}
132 		// String[] keys = { Constants.FRAMEWORK_STORAGE,
133 		// Constants.FRAMEWORK_OS_NAME, Constants.FRAMEWORK_OS_VERSION,
134 		// Constants.FRAMEWORK_PROCESSOR, Constants.FRAMEWORK_SECURITY,
135 		// Constants.FRAMEWORK_TRUST_REPOSITORIES,
136 		// Constants.FRAMEWORK_WINDOWSYSTEM, Constants.FRAMEWORK_VENDOR,
137 		// Constants.FRAMEWORK_VERSION, Constants.FRAMEWORK_STORAGE_CLEAN,
138 		// Constants.FRAMEWORK_LANGUAGE, Constants.FRAMEWORK_UUID };
139 		// for (String key : keys)
140 		// log.debug(key + "=" + bc.getProperty(key));
141 	}
142 
143 	static void printSystemProperties(PrintStream out) {
144 		TreeMap<String, String> display = new TreeMap<>();
145 		for (Object key : System.getProperties().keySet())
146 			display.put(key.toString(), System.getProperty(key.toString()));
147 		for (String key : display.keySet())
148 			out.println(key + "=" + display.get(key));
149 	}
150 
151 	static Session openAdminSession(Repository repository) {
152 		return openAdminSession(repository, null);
153 	}
154 
155 	static Session openAdminSession(final Repository repository, final String workspaceName) {
156 		ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
157 		Thread.currentThread().setContextClassLoader(KernelUtils.class.getClassLoader());
158 		LoginContext loginContext;
159 		try {
160 			loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
161 			loginContext.login();
162 		} catch (LoginException e1) {
163 			throw new CmsException("Could not login as data admin", e1);
164 		} finally {
165 			Thread.currentThread().setContextClassLoader(currentCl);
166 		}
167 		return Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Session>() {
168 
169 			@Override
170 			public Session run() {
171 				try {
172 					return repository.login(workspaceName);
173 				} catch (RepositoryException e) {
174 					throw new CmsException("Cannot open admin session", e);
175 				}
176 			}
177 
178 		});
179 	}
180 
181 	static void asyncOpen(ServiceTracker<?, ?> st) {
182 		Runnable run = new Runnable() {
183 
184 			@Override
185 			public void run() {
186 				st.open();
187 			}
188 		};
189 		Activator.getInternalExecutorService().execute(run);
190 //		new Thread(run, "Open service tracker " + st).start();
191 	}
192 
193 	/**
194 	 * @return the {@link BundleContext} of the {@link Bundle} which provided this
195 	 *         class, never null.
196 	 * @throws CmsException if the related bundle is not active
197 	 */
198 	static BundleContext getBundleContext(Class<?> clzz) {
199 		Bundle bundle = FrameworkUtil.getBundle(clzz);
200 		BundleContext bc = bundle.getBundleContext();
201 		if (bc == null)
202 			throw new CmsException("Bundle " + bundle.getSymbolicName() + " is not active");
203 		return bc;
204 	}
205 
206 	static BundleContext getBundleContext() {
207 		return getBundleContext(KernelUtils.class);
208 	}
209 
210 	static boolean asBoolean(String value) {
211 		if (value == null)
212 			return false;
213 		switch (value) {
214 		case "true":
215 			return true;
216 		case "false":
217 			return false;
218 		default:
219 			throw new CmsException("Unsupported value for attribute " + DataModelNamespace.ABSTRACT + ": " + value);
220 		}
221 	}
222 
223 	private static URI safeUri(String uri) {
224 		if (uri == null)
225 			throw new CmsException("URI cannot be null");
226 		try {
227 			return new URI(uri);
228 		} catch (URISyntaxException e) {
229 			throw new CmsException("Dadly formatted URI " + uri, e);
230 		}
231 	}
232 
233 	private KernelUtils() {
234 
235 	}
236 }