Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jpaoletti.jpm.core.PresentationManager Maven / Gradle / Ivy
package jpaoletti.jpm.core;
import java.util.*;
import jpaoletti.jpm.converter.ClassConverterList;
import jpaoletti.jpm.converter.Converter;
import jpaoletti.jpm.converter.ConverterWrapper;
import jpaoletti.jpm.converter.ExternalConverters;
import jpaoletti.jpm.core.audit.AuditService;
import jpaoletti.jpm.core.log.JPMLogger;
import jpaoletti.jpm.core.monitor.Monitor;
import jpaoletti.jpm.menu.MenuItemLocation;
import jpaoletti.jpm.menu.MenuItemLocationsParser;
import jpaoletti.jpm.parser.*;
import jpaoletti.jpm.security.core.PMSecurityConnector;
import jpaoletti.jpm.util.Properties;
import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.log4j.Logger;
/**
* Main engine class.
*
* @author jpaoletti
*/
public class PresentationManager extends Observable {
private static PresentationManager instance; // Singleton
private static final String DEFAULT_CONVERTER = "default-converter";
private static final String PERSISTENCE_MANAGER = "persistence-manager";
private static final String SECURITY_CONNECTOR = "security-connector";
private ResourceBundle bundle;
private static Long sessionIdSeed = 0L;
private Properties cfg;
private JPMLogger logger;
private Map entities;
private Map locations;
private Map monitors;
private List externalConverters;
private ClassConverterList classConverters;
private String persistenceManager;
private boolean error;
private final Map sessions = new HashMap();
private Timer sessionChecker;
private PMSecurityConnector securityConnector;
private AuditService auditService;
private String cfgFilename;
/**
* Default constructor with default configuration name "jpm-config.xml".
*/
public PresentationManager() {
this("jpm-config.xml");
}
/**
* Constructor with configuration file name.
*/
public PresentationManager(String cfgFilename) {
this.cfgFilename = cfgFilename;
if (instance == null) {
if (initialize()) {
instance = this;
} else {
instance = null;
}
} else {
instance.warn("Trying to initialize the already initialized PM. Ignoring");
}
}
/**
* Initialize the Presentation Manager singleton
*
* @param configurationFilename File name for a configuration file
* @param log a PrintStream for logs
*
* @return true if initialization was success, false otherwies
*/
public static boolean start(final String configurationFilename) {
try {
if (getPm() == null) {
instance = new PresentationManager(configurationFilename);
}
return isActive();
} catch (Exception ex) {
instance = null;
Logger.getRootLogger().fatal("Unable to initialize jPM", ex);
return false;
}
}
/**
* @return true if jpm is active
*/
public static boolean isActive() {
return getPm() != null;
}
/**
* Initialize the Presentation Manager.
*
* @param log a PrintStream for logs
*
* @return true if initialization was success, false otherwies
*/
public final boolean initialize() {
notifyObservers();
try {
this.cfg = (Properties) new MainParser(this).parseFile(getCfgFilename());
} catch (Exception ex) {
ex.printStackTrace(); //Deep trouble
error = true;
return false;
}
logger = (JPMLogger) newInstance(getCfg().getProperty("logger-class", "jpaoletti.jpm.core.log.Log4jLogger"));
logger.setName(getCfg().getProperty("logger-name", "jPM"));
error = false;
try {
try {
Class.forName(getDefaultDataAccess());
logItem("Default Data Access", getDefaultDataAccess(), "*");
} catch (Exception e) {
logItem("Default Data Access", getDefaultDataAccess(), "?");
}
logItem("Template", getTemplate(), "*");
logItem("Menu", getMenu(), "*");
logItem("Application version", getAppversion(), "*");
logItem("Title", getTitle(), "*");
logItem("Subtitle", getSubtitle(), "*");
logItem("Contact", getContact(), "*");
logItem("Default Converter", getDefaultConverterClass(), "*");
final String _securityConnector = getCfg().getProperty(SECURITY_CONNECTOR);
if (_securityConnector != null) {
try {
securityConnector = (PMSecurityConnector) newInstance(_securityConnector);
logItem("Security Connector", _securityConnector, "*");
} catch (Exception e) {
error = true;
logItem("Security Connector", _securityConnector, "?");
}
} else {
securityConnector = null;
}
persistenceManager = cfg.getProperty(PERSISTENCE_MANAGER, "jpaoletti.jpm.core.PersistenceManagerVoid");
try {
newInstance(persistenceManager);
logItem("Persistance Manager", persistenceManager, "*");
} catch (Exception e) {
error = true;
logItem("Persistance Manager", persistenceManager, "?");
}
loadEntities();
loadMonitors();
loadConverters();
loadClassConverters();
loadLocations();
createSessionChecker();
customLoad();
} catch (Exception exception) {
error(exception);
error = true;
}
if (error) {
error("error: One or more errors were found. Unable to start jPM");
}
return !error;
}
public String getTitle() {
return cfg.getProperty("title", "pm.title");
}
public String getTemplate() {
return cfg.getProperty("template", "default");
}
public boolean isDebug() {
return "true".equals(cfg.getProperty("debug"));
}
public String getAppversion() {
return cfg.getProperty("appversion", "1.0.0");
}
public String getDefaultConverterClass() {
return getCfg().getProperty(DEFAULT_CONVERTER);
}
private void loadMonitors() {
PMParser parser = new MonitorParser(this);
final Map result = new HashMap();
final List monitorNames = getAll("monitor");
for (String monitorName : monitorNames) {
try {
final Monitor m = (Monitor) parser.parseFile(monitorName);
result.put(m.getId(), m);
result.put(monitorNames.indexOf(monitorName), m);
m.getSource().init();
Thread thread = new Thread(m);
m.setThread(thread);
thread.start();
logItem("[Monitor] " + m.getId(), m.getSource().getClass().getName(), "*");
} catch (Exception exception) {
error(exception);
logItem("[Monitor] " + monitorName, null, "!");
}
}
monitors = result;
}
/**
* Formatting helper for startup
*
* @param evt The event
* @param s1 Text
* @param s2 Extra description
* @param symbol Status symbol
*/
public void logItem(String s1, String s2, String symbol) {
info(String.format("(%s) %-25s %s", symbol, s1, (s2 != null) ? s2 : ""));
}
private void loadLocations() {
final MenuItemLocationsParser parser = new MenuItemLocationsParser(this, getCfg().getProperty("locations", "jpm-locations.xml"));
locations = parser.getLocations();
if (locations == null || locations.isEmpty()) {
warn("No locations defined!");
}
if (parser.hasError()) {
error = true;
}
}
private void loadEntities() {
EntityParser parser = new EntityParser(this);
if (entities == null) {
entities = new HashMap();
} else {
entities.clear();
}
final List ss = getAll("entity");
for (String s : ss) {
try {
final Entity e = (Entity) parser.parseFile(s);
if (e.hasSelectedScopeOperations() && !e.isIdentified()) {
error("Entity " + e.getId() + " has selected scope operations and idField is not defined");
logItem("[Entity] " + e.getId(), e.getClazz(), "!");
error = true;
} else {
if (e.getFields() != null) {
for (Field field : e.getFields()) {
field.setEntity(e);
}
}
try {
Class.forName(e.getClazz());
entities.put(e.getId(), e);
entities.put(ss.indexOf(s), e);
if (e.isWeak()) {
logItem("[Entity] " + e.getId(), e.getClazz(), "\u00b7");
} else {
logItem("[Entity] " + e.getId(), e.getClazz(), "*");
}
} catch (ClassNotFoundException cnte) {
logItem("[Entity] " + e.getId(), e.getClazz(), "?");
error = true;
}
}
} catch (Exception exception) {
error(exception);
logItem("[Entity] " + s, "???", "!");
error = true;
}
}
}
/**
* Return the list of weak entities of the given entity.
*
* @param e The strong entity
* @return The list of weak entities
*/
public List weakEntities(Entity e) {
final List res = new ArrayList();
for (Entity entity : getEntities().values()) {
if (entity.getOwner() != null && entity.getOwner().getEntityId().compareTo(e.getId()) == 0) {
res.add(entity);
}
}
if (res.isEmpty()) {
return null;
} else {
return res;
}
}
/**
* Return the entity of the given id
*
* @param id Entity id
* @return The entity
*/
public Entity getEntity(String id) {
Entity e = getEntities().get(id);
if (e == null) {
return null;
}
return e;
}
/**
* Return the location of the given id
*
* @param id The location id
* @return The MenuItemLocation
*/
public MenuItemLocation getLocation(String id) {
return locations.get(id);
}
/**
* Return the monitor of the given id
*
* @param id The monitor id
* @return The monitor
*/
public Monitor getMonitor(String id) {
return getMonitors().get(id);
}
/**
* Create and fill a new Entity Container
*
* @param id Entity id
* @return The container
*/
public EntityContainer newEntityContainer(String id) {
final Entity e = lookupEntity(id);
if (e == null) {
return null;
}
e.setWeaks(weakEntities(e));
return new EntityContainer(e);
}
/**
* Looks for an Entity with the given id
*/
private Entity lookupEntity(String sid) {
for (Integer i = 0; i < getEntities().size(); i++) {
Entity e = getEntities().get(i);
if (e != null && sid.compareTo(EntityContainer.buildId(e.getId())) == 0) {
return getEntity(e.getId());
}
}
return null;
}
/*
* Getters
*/
/**
* Getter for contact
*
* @return
*/
public String getContact() {
return cfg.getProperty("contact", "");
}
/**
* Getter for default data access
*
* @return
*/
public String getDefaultDataAccess() {
return cfg.getProperty("default-data-access", "jpaoletti.jpm.core.DataAccessVoid");
}
/**
* Getter for entities map
*
* @return
*/
public Map getEntities() {
return entities;
}
/**
* Getter for location map
*
* @return
*/
public Map getLocations() {
return locations;
}
/**
* Getter for login required
*
* @return
*/
public boolean isLoginRequired() {
return securityConnector != null;
}
/**
* Getter for monitor map
*
* @return
*/
public Map getMonitors() {
return monitors;
}
/**
* Create a new instance of the persistance manager
*
* @return
*/
public PersistenceManager newPersistenceManager() {
return (PersistenceManager) newInstance(persistenceManager);
}
/**
* Getter for singleton pm
*
* @return
*/
public static PresentationManager getPm() {
return instance;
}
/*
* Loggin helpers
*/
/**
* If debug flag is active, create a debug information log
*
* @param invoquer The invoquer of the debug
* @param o Object to log
*/
public void debug(Object invoquer, Object o) {
if (logger.isDebugEnabled()) {
logger.debug("[" + invoquer.getClass().getName() + "] " + o);
}
}
/**
* Generate an info entry on the local logger
*
* @param o Object to log
*/
public void info(Object o) {
logger.info(o);
}
/**
* Generate a warn entry on the local logger
*
* @param o Object to log
*/
public void warn(Object o) {
if (o instanceof Throwable) {
logger.warn(o, (Throwable) o);
} else {
logger.warn(o);
}
}
/**
* Generate an error entry on the local logger
*
* @param o Object to log
*/
public void error(Object o) {
if (o instanceof Throwable) {
logger.error(o, (Throwable) o);
} else {
logger.error(o);
}
}
/*
* Helpers for bean management
*/
/**
* Getter for an object property value as String
*
* @param obj The object
* @param propertyName The property
* @return The value of the property of the object as string
*
*/
public String getAsString(Object obj, String propertyName) {
Object o = get(obj, propertyName);
if (o != null) {
return o.toString();
} else {
return "";
}
}
/**
* Getter for an object property value
*
* @param obj The object
* @param propertyName The property
* @return The value of the property of the object
*
*/
public Object get(Object obj, String propertyName) {
try {
if (obj != null && propertyName != null) {
return PropertyUtils.getNestedProperty(obj, propertyName);
}
} catch (NullPointerException e) {
} catch (NestedNullException e) {
} catch (Exception e) {
// Now I don't like it.
error(e);
return "-undefined-";
}
return null;
}
/**
* Setter for an object property value
*
* @param obj The object
* @param name The property name
* @param value The value to set
*
*/
public void set(Object obj, String name, Object value) {
try {
PropertyUtils.setNestedProperty(obj, name, value);
} catch (Exception e) {
error(e);
}
}
/**
* Creates a new instance object of the given class.
*
* @param clazz The Class of the new Object
* @return The new Object or null on any error.
*/
public Object newInstance(String clazz) {
try {
return Class.forName(clazz).newInstance();
} catch (Exception e) {
error(e);
return null;
}
}
private void loadConverters() {
final PMParser parser = new ExternalConverterParser(this);
externalConverters = new ArrayList();
final List ss = getAll("external-converters");
for (String s : ss) {
try {
final ExternalConverters ec = (ExternalConverters) parser.parseFile(s);
externalConverters.add(ec);
logItem("[ExternalConverter] " + s, null, "*");
} catch (Exception exception) {
error(exception);
logItem("[ExternalConverter] " + s, null, "!");
}
}
//Check repeated ids
final List ids = new ArrayList();
for (ExternalConverters ec : externalConverters) {
for (ConverterWrapper cw : ec.getConverters()) {
if (ids.contains(cw.getId())) {
logItem("[ExternalConverter] Repeated id: " + cw.getId(), null, "!");
error = true;
} else {
ids.add(cw.getId());
}
}
}
}
private void loadClassConverters() {
final PMParser parser = new ClassConverterParser(this);
final String classConvertersFile = getCfg().getProperty("class-converters");
if (classConvertersFile != null) {
try {
classConverters = (ClassConverterList) parser.parseFile(classConvertersFile);
logItem("[ClassConverters] " + classConvertersFile, null, "*");
} catch (Exception exception) {
error(exception);
logItem("[ClassConverters] " + classConvertersFile, null, "!");
}
} else {
logItem("[ClassConverters] - ", null, "*");
classConverters = new ClassConverterList(this);
}
}
public Converter findExternalConverter(String id) {
for (ExternalConverters ecs : getExternalConverters()) {
ConverterWrapper w = ecs.getWrapper(id);
if (w != null) {
return w.getConverter();
}
}
return null;
}
/**
* Getter for the list of external converters
*/
public List getExternalConverters() {
return externalConverters;
}
/**
* Creates a new session with the given id. If null is used, an automatic
* session id will be generated
*
* @param sessionId The new session id. Must be unique.
* @throws PMException on already defined session
* @return New session
*/
public PMSession registerSession(String sessionId) {
synchronized (sessions) {
if (sessionId != null) {
if (!sessions.containsKey(sessionId)) {
sessions.put(sessionId, new PMSession(sessionId));
}
return getSession(sessionId);
} else {
return registerSession(newSessionId());
}
}
}
/**
* Return the session for the given id
*
* @param sessionId The id of the wanted session
* @return The session
*/
public PMSession getSession(String sessionId) {
final PMSession s = sessions.get(sessionId);
if (s != null) {
s.setLastAccess(new Date());
}
return s;
}
/**
* Getter for the session map.
*
* @return Sessions
*/
public Map getSessions() {
return sessions;
}
/**
* Removes the given id session
*/
public void removeSession(String sessionId) {
sessions.remove(sessionId);
}
public Properties getCfg() {
return cfg;
}
public String getSubtitle() {
return cfg.getProperty("subtitle", "pm.subtitle");
}
private void createSessionChecker() {
final Long timeout = Long.parseLong(cfg.getProperty("session-timeout", "3600")) * 1000;
final int interval = Integer.parseInt(cfg.getProperty("session-check-interval", "300")) * 1000;
if (sessionChecker != null) {
sessionChecker.cancel();
}
sessionChecker = new Timer();
sessionChecker.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
synchronized (sessions) {
final List toRemove = new ArrayList();
for (Map.Entry entry : sessions.entrySet()) {
if (entry.getValue().getLastAccess().getTime() + timeout < System.currentTimeMillis()) {
toRemove.add(entry.getKey());
}
}
for (String session : toRemove) {
removeSession(session);
}
}
}
}, 0, interval);
}
public String getCopyright() {
return cfg.getProperty("copyright", "jpaoletti");
}
public String getMenu() {
return cfg.getProperty("menu", "jpm-menu.xml");
}
public boolean isHideableHeader() {
return "true".equalsIgnoreCase(cfg.getProperty("hideable-header", "false"));
}
public static synchronized String newSessionId() {
sessionIdSeed++;
final MD5 md5 = new MD5();
return md5.calcMD5(sessionIdSeed.toString());
}
/**
* Returns the internacionalized string for the given key
*/
public String message(String key, Object... params) {
if (key == null) {
return null;
}
try {
String string = (getResourceBundle().containsKey(key)) ? getResourceBundle().getString(key) : key;
if (params != null) {
for (int i = 0; i < params.length; i++) {
String param = (params[i] == null) ? "" : params[i].toString();
string = string.replaceAll("\\{" + i + "\\}", param);
}
}
return string;
} catch (Exception e) {
return key;
}
}
/**
* Returns the internacionalized string for the given key
*/
public static String getMessage(String key, Object... params) {
return getPm().message(key, params);
}
public Converter getDefaultConverter() {
try {
if (getDefaultConverterClass() != null && !"".equals(getDefaultConverterClass().trim())) {
return (Converter) newInstance(getDefaultConverterClass());
}
} catch (Exception e) {
}
return null;
}
public PMSession getSessionByUser(final String username) {
for (PMSession s : sessions.values()) {
if (s.getUser() != null && s.getUser().getUsername().equals(username)) {
return s;
}
}
return null;
}
//TODO Check security connector and its context
public PMSecurityConnector getSecurityConnector(PMContext ctx) {
securityConnector.setContext(ctx);
return securityConnector;
}
public List getAll(String name) {
return cfg.getAll(name);
}
public boolean allowMultipleLogin() {
return "true".equalsIgnoreCase(cfg.getProperty("multi-login", "true"));
}
/**
* Returns local resource bundle for internationalization
*/
public ResourceBundle getResourceBundle() {
if (bundle == null) {
String lang = "";
String country = "";
final String _locale = getPm().getCfg().getProperty("locale", "");
if (_locale != null && !"".equals(_locale.trim())) {
final String[] __locale = _locale.split("[_]");
lang = __locale[0];
if (__locale.length > 1) {
country = __locale[1];
}
}
final Locale locale = new Locale(lang, country);
bundle = ResourceBundle.getBundle("ApplicationResource", locale);
}
return bundle;
}
/**
* @return the cfgFilename
*/
public String getCfgFilename() {
return cfgFilename;
}
/**
* @param cfgFilename the cfgFilename to set
*/
protected final void setCfgFilename(String cfgFilename) {
this.cfgFilename = cfgFilename;
}
public ClassConverterList getClassConverters() {
return classConverters;
}
/**
* Search external converter by id
*/
public Converter getExternalConverter(String id) {
for (ExternalConverters ec : getExternalConverters()) {
for (ConverterWrapper cw : ec.getConverters()) {
if (cw.getId().equals(id)) {
return cw.getConverter();
}
}
}
return null;
}
/**
* Returns audit service
*/
public AuditService getAuditService() {
if (auditService == null) {
auditService = (AuditService) newInstance(cfg.getProperty("audit-service", "jpaoletti.jpm.core.audit.SimpleAudit"));
auditService.setLevel(cfg.getInt("audit-level", -1));
}
return auditService;
}
/**
* Executes a custom loader.
*/
private void customLoad() {
final String s = getCfg().getProperty("custom-loader");
if (s != null) {
try {
final CustomLoader customLoader = (CustomLoader) Class.forName(s).newInstance();
logItem("Custom Loader", s, "*");
customLoader.execute(this);
} catch (ClassNotFoundException e) {
error = true;
logItem("Custom Loader", s, "?");
} catch (Exception e) {
error = true;
error(e);
logItem("Custom Loader Failed", s, "!");
}
}
}
}