
com.semanticcms.core.servlet.SemanticCMS Maven / Gradle / Ivy
/*
* semanticcms-core-servlet - Java API for modeling web page content and relationships in a Servlet environment.
* Copyright (C) 2014, 2015, 2016 AO Industries, Inc.
* [email protected]
* 7262 Bull Pen Cir
* Mobile, AL 36695
*
* This file is part of semanticcms-core-servlet.
*
* semanticcms-core-servlet is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* semanticcms-core-servlet is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with semanticcms-core-servlet. If not, see .
*/
package com.semanticcms.core.servlet;
import com.aoindustries.servlet.http.Dispatcher;
import com.aoindustries.util.PropertiesUtils;
import com.aoindustries.util.WrappedException;
import com.semanticcms.core.model.Book;
import com.semanticcms.core.model.PageRef;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/**
* The SemanticCMS application context.
*
* TODO: Consider custom EL resolver for this variable: http://stackoverflow.com/questions/5016965/how-to-add-a-custom-variableresolver-in-pure-jsp
*/
public class SemanticCMS {
//
static final String ATTRIBUTE_NAME = "semanticCMS";
private static final Object instanceLock = new Object();
/**
* Gets the SemanticCMS instance, creating it if necessary.
*/
public static SemanticCMS getInstance(ServletContext servletContext) {
try {
synchronized(instanceLock) {
SemanticCMS semanticCMS = (SemanticCMS)servletContext.getAttribute(SemanticCMS.ATTRIBUTE_NAME);
if(semanticCMS == null) {
semanticCMS = new SemanticCMS(servletContext);
servletContext.setAttribute(SemanticCMS.ATTRIBUTE_NAME, semanticCMS);
}
return semanticCMS;
}
} catch(IOException e) {
throw new WrappedException(e);
}
}
private SemanticCMS(ServletContext servletContext) throws IOException {
this.demoMode = Boolean.parseBoolean(servletContext.getInitParameter(DEMO_MODE_INIT_PARAM));
this.rootBook = initBooks(servletContext);
}
//
//
private static final String DEMO_MODE_INIT_PARAM = "com.semanticcms.core.servlet.SemanticCMS.demoMode";
private final boolean demoMode;
/**
* When true, a cursory attempt will be made to hide sensitive information for demo mode.
*/
public boolean getDemoMode() {
return demoMode;
}
//
//
private static final String BOOKS_PROPERTIES_RESOURCE = "/WEB-INF/books.properties";
private static final String BOOKS_ATTRIBUTE_NAME = "books";
private static final String MISSING_BOOKS_ATTRIBUTE_NAME = "missingBooks";
private static final String ROOT_BOOK_ATTRIBUTE_NAME = "rootBook";
private static String getProperty(Properties booksProps, Set
//
/**
* The parameter name used for views.
*/
public static final String VIEW_PARAM = "view";
/**
* The default view is the content view and will have the empty view name.
*/
public static final String DEFAULT_VIEW_NAME = "content";
private final Object viewsLock = new Object();
/**
* The views by name in order added.
*/
private final Map viewsByName = new LinkedHashMap();
private static final Set extends View.Group> viewGroups = Collections.unmodifiableSet(EnumSet.allOf(View.Group.class));
/**
* Gets all view groups.
*/
public Set extends View.Group> getViewGroups() {
return viewGroups;
}
/**
* Gets the views in order added.
*/
public Map getViewsByName() {
return Collections.unmodifiableMap(viewsByName);
}
/**
* The views in order.
*/
private final SortedSet views = new TreeSet();
/**
* Gets the views, ordered by view group then display.
*
* @see View#compareTo(com.semanticcms.core.servlet.View)
*/
public SortedSet getViews() {
return Collections.unmodifiableSortedSet(views);
}
/**
* Registers a new view.
*
* @throws IllegalStateException if a view is already registered with the name.
*/
public void addView(View view) throws IllegalStateException {
String name = view.getName();
synchronized(viewsLock) {
if(viewsByName.containsKey(name)) throw new IllegalStateException("View already registered: " + name);
if(viewsByName.put(name, view) != null) throw new AssertionError();
if(!views.add(view)) throw new AssertionError();
}
}
//
//
/**
* The themes in order added.
*/
private final Map themes = new LinkedHashMap();
/**
* Gets the themes, in the order added.
*/
public Map getThemes() {
synchronized(themes) {
// Not returning a copy since themes are normally only registered on app start-up.
return Collections.unmodifiableMap(themes);
}
}
/**
* Registers a new theme.
*
* @throws IllegalStateException if a theme is already registered with the name.
*/
public void addTheme(Theme theme) throws IllegalStateException {
String name = theme.getName();
synchronized(themes) {
if(themes.containsKey(name)) throw new IllegalStateException("Theme already registered: " + name);
if(themes.put(name, theme) != null) throw new AssertionError();
}
}
//
//
/**
* The CSS links in the added.
*/
private final Set cssLinks = new LinkedHashSet();
/**
* Gets the CSS links, in the order added.
*/
public Set extends String> getCssLinks() {
synchronized(cssLinks) {
// Not returning a copy since CSS links are normally only registered on app start-up.
return Collections.unmodifiableSet(cssLinks);
}
}
/**
* Registers a new CSS link.
*
* @throws IllegalStateException if the link is already registered.
*/
public void addCssLink(String cssLink) throws IllegalStateException {
synchronized(cssLinks) {
if(!cssLinks.add(cssLink)) throw new IllegalStateException("CSS link already registered: " + cssLinks);
}
}
//
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy