BrightSide Workbench Full Report + Source Code
ElephantContext.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2013 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.elephant.context;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.util.ArrayList;
26 import java.util.Currency;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
32 import javax.servlet.ServletContext;
33 import javax.servlet.ServletContextEvent;
34 import javax.servlet.ServletContextListener;
35 import javax.servlet.annotation.WebListener;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38 import org.turro.string.Strings;
39 import org.apache.commons.codec.binary.Base64;
40 import org.jdom.Document;
41 import org.jdom.Element;
42 import org.jdom.JDOMException;
43 import org.jdom.input.SAXBuilder;
44 import org.jdom.output.XMLOutputter;
45 import org.turro.annotation.ElephantConstructor;
46 import org.turro.collections.CollectionUtil;
47 import org.turro.config.Configurator;
48 import org.turro.elephant.impl.security.Cipher;
49 import org.turro.file.Folder;
50 import org.turro.json.Jsons;
51 import org.turro.path.Path;
52 import org.turro.reflection.Instances;
53 
58 @WebListener
59 public class ElephantContext implements ServletContextListener {
60 
61  private static ServletContext _context;
62  private static ArrayList<String> _metas;
63 
64  /* ServletContextListener */
65 
66  // Required to load listener
67  public ElephantContext() {
68  }
69 
70  @Override
71  public void contextDestroyed(ServletContextEvent event) {
72  _context = null;
73  }
74 
75  @Override
76  public void contextInitialized(ServletContextEvent event) {
77  _context = event.getServletContext();
78  loadSiteConfiguration();
79  Configurator.init(ElephantContext.getRealPath("/WEB-INF/elephant/conf/configurator/context.json"));
80  }
81 
82  /* Site */
83 
84  public static Jsons siteInfo() {
85  return Jsons.object()
86  .add("name", ElephantContext.getSiteName())
87  .add("description", ElephantContext.getSiteDescription())
89  .add("url", ElephantContext.getServerUrl("http"))
90  .add("locales", ElephantContext.getSiteLocales());
91  }
92 
93  /* Helpers */
94 
95  public static ServletContext getCurrent() {
96  return _context;
97  }
98 
99  public static IConstructor createConstructor() {
100  return ElephantContext.getConstructor(null, null);
101  }
102 
103  public static List<String> getMetas() {
104  return _metas;
105  }
106 
107  public static String removeWebContext(String path) {
108  String remove = getRootWebPath();
109  if(!Strings.isBlank(remove) && path.startsWith(remove)) {
110  return path.substring(remove.length());
111  }
112  return path;
113  }
114 
115  public static String getRealPath(String path) {
116  String real = getCurrent().getRealPath(path);
117  if(real != null) {
118  real = real.replaceAll("\\\\", "/");
119  if(real.endsWith("/"))
120  real = real.substring(0, real.length() - 1);
121  }
122  return real;
123  }
124 
125  public static String getRelativePath(String path) {
126  String remove = getRealPath("/");
127  if(path.startsWith(remove)) {
128  return path.substring(remove.length());
129  }
130  return null;
131  }
132 
133  public static String getContextVariable(IConstructor constructor) {
134  return constructor.getCurrentContext().getPath();
135  }
136 
137  public static String getRootWebPath() {
138  return _context.getContextPath();
139  }
140 
141  public static String getRootResourcePath() {
142  return getRootWebPath();
143  }
144 
145  public static Object getAttribute(String key) {
146  return _context.getAttribute(key);
147  }
148 
149  public static void setAttribute(String key, Object value) {
150  _context.setAttribute(key, value);
151  }
152 
153  public static void removeAttribute(String key) {
154  _context.removeAttribute(key);
155  }
156 
157  public static String getSiteName() {
158  return (String) getAttribute("site_name");
159  }
160 
161  public static String getSiteForcedDomain() {
162  return (String) getAttribute("site_forced-domain");
163  }
164 
165  public static String getSiteDescription() {
166  return (String) getAttribute("site_description");
167  }
168 
169  public static String getSiteKeywords() {
170  return (String) getAttribute("site_keywords");
171  }
172 
173  public static String getSiteFonts() {
174  return (String) getAttribute("site_fonts");
175  }
176 
177  public static String getSiteIcon() {
178  return (String) getAttribute("site_icon");
179  }
180 
181  public static String getSiteWelcome() {
182  return (String) getAttribute("site_welcome");
183  }
184 
185  public static String getSiteInternalFiles() {
186  return (String) getAttribute("site-files");
187  }
188 
189  public static String getEncoding() {
190  return (String) getAttribute("site_encoding");
191  }
192 
193  public static String getContextLoad() {
194  return (String) getAttribute("site_context-load");
195  }
196 
197  public static String getSiteLocales() {
198  return (String) getAttribute("site_locales");
199  }
200 
201  public static boolean isValidLocale(Locale locale) {
202  return getSiteLocales().contains(locale.getLanguage());
203  }
204 
205  public static String getSiteSignin() {
206  return (String) getAttribute("site_signin");
207  }
208 
209  public static String getSiteSyndicate() {
210  return (String) getAttribute("site_syndicate");
211  }
212 
213  public static String getDirectoryQualification() {
214  return (String) getAttribute("site_directory-qualification");
215  }
216 
217  public static String getTemplatesRoot() {
218  return (String) getAttribute("site_templatesRoot");
219  }
220 
221  public static boolean getUseSSL() {
222  return "true".equals((String) getAttribute("site_use-ssl"));
223  }
224 
225  public static boolean getUseSSO() {
226  return "true".equals((String) getAttribute("site_use-sso"));
227  }
228 
229  public static boolean getLiveLinks() {
230  return "true".equals((String) getAttribute("site_live-links"));
231  }
232 
233  public static Locale getContactLocale() {
234  return new Locale((String) getAttribute("contact_language"), (String) getAttribute("contact_country"));
235  }
236 
237  public static Currency getContactCurrency() {
238  return Currency.getInstance((String) getAttribute("contact_currency"));
239  }
240 
241  public static boolean hasSignup() {
242  return Folder.from(ElephantContext.getRealPath("/user/signup")).exists() &&
243  "true".equals((String) getAttribute("site_has_signup"));
244  }
245 
246  public static String getServerBase(String scheme) {
247  if(scheme.equals("http") && getUseSSL()) {
248  scheme = "https";
249  }
250  String server = schemes.get(scheme);
251  if(server == null) {
252  server = scheme + "://" + getSiteForcedDomain();
253  }
254  return server;
255  }
256 
257  public static String getServerUrl(String scheme) {
258  return getServerBase(scheme) + getRootWebPath();
259  }
260 
261  public static URI toUri(String localPath) throws URISyntaxException {
262  return new URI(getServerBase("http") + getRootWebPath() + localPath);
263  }
264 
265  public static byte[] encrypt(byte[] value) {
266  return Cipher.symetricEncrypt(value);
267  }
268 
269  public static byte[] decrypt(byte[] value) {
270  return (value != null && ((value.length % 8) == 0)) ?
271  Cipher.symetricDecrypt(value) : null;
272  }
273 
274  public static String encrypt(String value) {
275  return !Strings.isBlank(value) ? new String(
276  new Base64().encode(encrypt(value.getBytes()))) : "";
277  }
278 
279  public static String decrypt(String value) {
280  if(!Strings.isBlank(value)) {
281  byte[] bytes = decrypt(new Base64().decode(value.getBytes()));
282  return bytes != null ? new String(bytes) : "";
283  }
284  return null;
285  }
286 
287  public static File file(String path) {
288  return new File(getRealPath(path));
289  }
290 
291  public static String logMsg(String msg) {
292  return "[" + getSiteName() + "]" + (Strings.isBlank(msg) ? "" : ": " + msg);
293  }
294 
295  public static void resetSite() {
296  loadSiteConfiguration();
297  }
298 
299  public static void resetSchemes() {
300  schemes.clear();
301  }
302 
303  private final static String
304  SITE_FILE = "/WEB-INF/elephant/conf/site.xml";
305 
306  private static void loadSiteConfiguration() {
307  Element conf = null;
308  SAXBuilder builder = new SAXBuilder();
309  Document doc;
310  try {
311  File confFile = new File(getRealPath(SITE_FILE));
312  if(confFile.exists()) {
313  doc = builder.build(confFile);
314  conf = doc.getRootElement();
315  }
316  if(conf != null) {
317  setAttribute("site_name", readAttribute(conf.getChild("name"), "value", "Elephant"));
318  setAttribute("site_forced-domain", conf.getChildText("force-domain"));
319  setAttribute("site_description", conf.getChildText("description"));
320  setAttribute("site_keywords", conf.getChildText("keywords"));
321  setAttribute("site_fonts", conf.getChildText("fonts"));
322  setAttribute("site_icon", conf.getChildText("icon"));
323  setAttribute("site_welcome", conf.getChildText("welcome"));
324  setAttribute("site_internal-files", conf.getChildText("internalFiles"));
325  setAttribute("site_encoding", readAttribute(conf.getChild("encoding"), "value", "ISO-8859-1"));
326  setAttribute("site_context-load", readAttribute(conf.getChild("context-load"), "value", "none"));
327  setAttribute("site_locales", readAttribute(conf.getChild("locales"), "value", "_en,_ca"));
328  setAttribute("site_use-ssl", conf.getChildText("use-ssl"));
329  setAttribute("site_use-sso", Strings.isBlank(conf.getChildText("use-sso"), "true"));
330  setAttribute("site_live-links", Strings.isBlank(conf.getChildText("live-links"), "true"));
331  String gs = conf.getChildText("syndicate");
332  setAttribute("site_syndicate", Strings.isBlank(gs) ? "Guests" : gs);
333  String qualification = conf.getChildText("directory-qualification");
334  setAttribute("site_directory-qualification", Strings.isBlank(qualification) ? "any,!guest" : qualification);
335  setAttribute("rootWebPath", getRootWebPath());
336  String tmplRoot = conf.getChildText("templates-root");
337  setAttribute("site_templatesRoot", Strings.isBlank(tmplRoot) ? "templates" : tmplRoot);
338  setAttribute("site_has_signup", Strings.isBlank(conf.getChildText("has-signup"), "true"));
339  String signin = conf.getChildText("signin");
340  setAttribute("site_signin", signin);
341  if(Strings.isBlank(signin) || "all".equals(signin)) {
342  setAttribute("signPersona", true);
343  setAttribute("signInternal", true);
344  } else if("persona".equals(signin)) {
345  setAttribute("signPersona", true);
346  setAttribute("signInternal", false);
347  } else if("internal".equals(signin)) {
348  setAttribute("signPersona", false);
349  setAttribute("signInternal", true);
350  }
351  _metas = new ArrayList<>();
352  for(Element meta : (List<Element>) conf.getChildren("meta")) {
353  _metas.add(new XMLOutputter().outputString(meta));
354  }
355  setAttribute("contact_language", readAttribute(conf.getChild("contact-defaults"), "language", "ca"));
356  setAttribute("contact_country", readAttribute(conf.getChild("contact-defaults"), "country", "ES"));
357  setAttribute("contact_currency", readAttribute(conf.getChild("contact-defaults"), "currency", "EUR"));
358  }
359  } catch (IOException | JDOMException ex) {
360  Logger.getLogger(ElephantContext.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
361  }
362  }
363 
364  private static String readAttribute(Element child, String attr, String def) {
365  return child != null ? child.getAttributeValue(attr) : def;
366  }
367 
368  private static final HashMap<String, String> schemes = new HashMap<>();
369 
370  public static void initServerSchemas(HttpServletRequest request) {
371  if(!schemes.containsKey(request.getScheme())) {
372  schemes.put(request.getScheme(), request.getScheme() + "://" +
373  request.getServerName() + getServerPort(request));
374  }
375  }
376 
377  private static String getServerPort(HttpServletRequest request) {
378  String scheme = request.getScheme();
379  int port = request.getServerPort();
380  if("http".equals(scheme) && port == 80) {
381  return "";
382  } else if("https".equals(scheme) && port == 443) {
383  return "";
384  } else if("ftp".equals(scheme) && port == 21) {
385  return "";
386  }
387  return ":" + port;
388  }
389 
390  /* Entity's context */
391 
392  private static final String ENTITY_WEB_CONTEXT = "entity-web-context";
393 
401  public static String getEntityWebContext(String path) {
402  String[] paths = path.split(",");
403  for(String p : paths) {
404  String ep = getEntityWebContext(new Path(p));
405  if(!Strings.isBlank(ep)) {
406  return ep;
407  }
408  }
409  return null;
410  }
411 
412  public static String getEntityWebContext(Path path) {
413  return ElephantProperties.getContextProperty(ENTITY_WEB_CONTEXT, path.getRoot());
414  }
415 
416 // /* Annotations */
417 //
418 // private static final Lock classesLock = new ReentrantLock();
419 // private static final Lock instancesLock = new ReentrantLock();
420 // private static Map<String, Set<String>> annotatedClasses;
421 // private static Map<String, Set<Object>> annotatedInstances;
422 //
423 // public static <T> T getInstanceByAnnotation(Class annotationClass, Class<T> type) {
424 // return getInstanceByAnnotation(annotationClass, type, false);
425 // }
426 //
427 // public static <T> T getInstanceByAnnotation(Class annotationClass, Class<T> type, boolean fresh) {
428 // Set<T> instances = ElephantContext.getInstancesByAnnotation(annotationClass, type, fresh);
429 // if(instances != null && !instances.isEmpty()) {
430 // return instances.iterator().next();
431 // }
432 // return null;
433 // }
434 //
435 // public static <T> Set<T> getInstancesByAnnotation(Class annotationClass, Class<T> type) {
436 // return getInstancesByAnnotation(annotationClass, type, false);
437 // }
438 //
439 // public static <T> Set<T> getInstancesByAnnotation(Class annotationClass, Class<T> type, boolean fresh) {
440 // if(annotatedInstances == null) {
441 // annotatedInstances = new HashMap<>();
442 // }
443 // Set<T> instances = (Set<T>) annotatedInstances.get(annotationClass.getName());
444 // if(fresh || instances == null) {
445 // instancesLock.lock();
446 // try {
447 // instances = (Set<T>) annotatedInstances.get(annotationClass.getName());
448 // if(fresh || instances == null) {
449 // instances = new HashSet<>();
450 // for(String className : getClassesByAnnotation(annotationClass.getName())) {
451 // Class javaClass = ReflectionUtil.classCheck(className);
452 // if(javaClass != null && ReflectionUtil.canCast(javaClass, type)) {
453 // T instance = (T) ReflectionUtil.instance(javaClass);
454 // if(instance != null) {
455 // instances.add(instance);
456 // }
457 // }
458 // }
459 // annotatedInstances.put(annotationClass.getName(), (Set<Object>) instances);
460 // }
461 // } finally {
462 // instancesLock.unlock();
463 // }
464 // }
465 // return instances;
466 // }
467 //
468 // public static Set<String> getClassesByAnnotation(Class annotationClass) {
469 // return getClassesByAnnotation(annotationClass.getName());
470 // }
471 //
472 // public static Set<String> getClassesByAnnotation(String annotationClass) {
473 // if(annotatedClasses == null) {
474 // annotatedClasses = new HashMap<>();
475 // }
476 // Set<String> classes = annotatedClasses.get(annotationClass);
477 // if(classes == null) {
478 // classesLock.lock();
479 // try {
480 // classes = annotatedClasses.get(annotationClass);
481 // if(classes == null) {
482 // classes = new HashSet<>();
483 // annotatedClasses.put(annotationClass, classes);
484 // classes.addAll(ClassNames.cached()
485 // .packages("org.turro")
486 // .byAnnotation(annotationClass));
487 // }
488 // } finally {
489 // classesLock.unlock();
490 // }
491 // }
492 // return classes;
493 // }
494 //
495 // public static void clearAnnotatedClasses() {
496 // annotatedClasses = null;
497 // }
498 //
499 // /* Subclasses */
500 //
501 // private static final Lock subclassLock = new ReentrantLock();
502 // private static Map<String, Set<String>> subClasses;
503 // private static Map<String, Set<Object>> subInstances;
504 //
505 // public static <T> Set<T> getInstancesBySuperclass(Class superClass, Class<T> type) {
506 // return getInstancesBySuperclass(superClass, type, false);
507 // }
508 //
509 // public static <T> Set<T> getInstancesBySuperclass(Class superClass, Class<T> type, boolean fresh) {
510 // if(subInstances == null) {
511 // subInstances = new HashMap<>();
512 // }
513 // Set<T> instances = (Set<T>) subInstances.get(superClass.getName());
514 // if(fresh || instances == null) {
515 // subclassLock.lock();
516 // try {
517 // instances = (Set<T>) subInstances.get(superClass.getName());
518 // if(fresh || instances == null) {
519 // instances = new HashSet<>();
520 // for(String javaClass : getClassesBySuperclass(superClass.getName())) {
521 // Class jClass = ReflectionUtil.classCheck(javaClass);
522 // if(jClass != null && ReflectionUtil.canCast(jClass, type)) {
523 // T instance = (T) ReflectionUtil.instance(jClass);
524 // if(instance != null) {
525 // instances.add(instance);
526 // }
527 // }
528 // }
529 // subInstances.put(superClass.getName(), (Set<Object>) instances);
530 // }
531 // } finally {
532 // subclassLock.unlock();
533 // }
534 // }
535 // return instances;
536 // }
537 //
538 // public static Set<String> getClassesBySuperclass(String superClass) {
539 // if(subClasses == null) {
540 // subClasses = new HashMap<>();
541 // }
542 // Set<String> classes = subClasses.get(superClass);
543 // if(classes == null) {
544 // subclassLock.lock();
545 // try {
546 // classes = subClasses.get(superClass);
547 // if(classes == null) {
548 // classes = new HashSet<>();
549 // subClasses.put(superClass, classes);
550 // classes.addAll(ClassNames.cached()
551 // .packages("org.turro")
552 // .bySuper(superClass));
553 // }
554 // } finally {
555 // subclassLock.unlock();
556 // }
557 // }
558 // return classes;
559 // }
560 
561  /* Constructor */
562 
563  public static IConstructor getConstructor(HttpServletRequest request, HttpServletResponse response) {
564  IConstructor impl = CollectionUtil.from(Instances.fresh().byAnnotation(ElephantConstructor.class, IConstructor.class)).first();
565  if(impl != null) {
566  impl.setRequest(request);
567  impl.setResponse(response);
568  }
569  return impl;
570  }
571 
572 }
void contextInitialized(ServletContextEvent event)
static void setAttribute(String key, Object value)
static String getServerBase(String scheme)
static boolean isValidLocale(Locale locale)
static void initServerSchemas(HttpServletRequest request)
static IConstructor getConstructor(HttpServletRequest request, HttpServletResponse response)
static String getServerUrl(String scheme)
void contextDestroyed(ServletContextEvent event)
static String getContextVariable(IConstructor constructor)
static String getEntityWebContext(String path)
static String getContextProperty(String context, String property)
static byte[] symetricEncrypt(byte[] inpBytes)
Definition: Cipher.java:63
static byte[] symetricDecrypt(byte[] inpBytes)
Definition: Cipher.java:69
void setRequest(ServletRequest request)
void setResponse(ServletResponse response)