/*
* Copyright 2010 Semafor Informatik & Energie AG, Basel, Switzerland
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.semafor.gendas.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ch.semafor.gendas.dao.ElementDao;
import ch.semafor.gendas.dao.ElementTypeDao;
import ch.semafor.gendas.dao.PropertyTypeDao;
import ch.semafor.gendas.model.CoreException;
import ch.semafor.gendas.model.Element;
import ch.semafor.gendas.model.ElementType;
import ch.semafor.gendas.model.Modification;
import ch.semafor.gendas.model.PropertyType;
/**
* Persistence service for Java Beans
*
* @author tar
*
*/
@Service("persistenceService")
public class PersistenceManagerImpl implements PersistenceManager {
@Resource
ElementDao elementDao;
@Resource
ElementTypeDao elementTypeDao;
@Resource
PropertyTypeDao propertyTypeDao;
PersistenceCache cache = null;
boolean useCache = true;
private final Logger logger = LoggerFactory.getLogger(PersistenceManagerImpl.class);
public PersistenceManagerImpl() {
this.cache = new PersistenceCache();
// logger.info("Cache created");
}
@SuppressWarnings("rawtypes")
// NOPMD by wildi on 9/21/10 6:34 AM
@Transactional
public ElementType createElementType(final Class beanClass, String idName, String versionName) {
final ElementType t = new ElementTypeCreator(elementTypeDao,
propertyTypeDao).create(beanClass, idName, versionName); // NOPMD by wildi on 9/21/10
// 6:30 AM
elementTypeDao.save(t);
return t;
}
@Transactional
public Element save(final Object bean, final Long id, final String idName,
final String idVersion) throws CoreException,
ElementCreationException {
return save(bean);
}
@Transactional
public Element save(final Object bean) // NOPMD by wildi on 9/21/10 6:30 AM
throws CoreException, ElementCreationException {
logger.info(bean.getClass().getCanonicalName());
final ElementCreator creator = new ElementCreator(elementTypeDao,
elementDao, propertyTypeDao, cache);
logger.debug("about to create element tree for {}", bean.toString());
final Element newElement = creator.create(bean, null);
logger.debug("created element tree: {}", bean.toString());
// eliminate empty nodes
newElement.crunch();
// do not change it, uses System.out.println
if (logger.isDebugEnabled()) {
newElement.print(0, "new Element after crunch()");
}
Element element = null;
Long id = newElement.getId();
if (id != null && id > 0L) {
element = elementDao.get(id);
}
if (element == null) {
element = new Element(newElement.getElementType());
}
List<Element> knownElements = new ArrayList<Element>();
knownElements.add(element);
element.assign(newElement, knownElements, elementDao);
if (logger.isDebugEnabled()) {
element.print(0, "Element after assign() before save()");
}
element = elementDao.save(element);
// invalidate cached element
//if( cache != null ){
cache.remove(element.getId(), Modification.MaxRevision);
//}
creator.resetMaps();
creator.setMatchingIdsAndVersions(bean, element, null);
logger.debug("bean {} persisted.", bean.getClass().getCanonicalName());
return element;
}
public List<Element> getAllElements() {
return elementDao.getAllActive();
}
@Transactional(readOnly = true)
public Object load(Long id)
throws CoreException, ElementCreationException { // NOPMD by wildi
// on 9/21/10
// 6:30 AM
return load(id, null);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Transactional(readOnly = true)
public Object load(final Long id, final Long revision) throws CoreException,
ElementCreationException {
final Element e = elementDao.get(id);
// logger.info("loaded element id {} use cache {}", id, useCache);
if (logger.isDebugEnabled()) {
e.print(0, "loaded element id " + id);
}
try {
final ElementCreator creator = new ElementCreator(elementTypeDao,
elementDao, propertyTypeDao, useCache?cache:null);
Object obj = creator.load(e, revision);
return obj;
} catch (SecurityException ex) {
throw new ElementCreationException(ex.getMessage());
} catch (IllegalArgumentException ex) {
throw new ElementCreationException(ex.getMessage());
}
}
@Transactional(readOnly = true)
public List<Modification> getModifications(final Long id) { // NOPMD by
// wildi on
// 9/21/10 6:35
// AM
final Element e = elementDao.get(id); // NOPMD by wildi on 9/21/10 6:35
// AM
return new ArrayList<Modification>(e.getModifications());
}
@Transactional(readOnly = true)
public Long getLastRevision(final Long id) { // NOPMD by wildi on 9/21/10
// 6:35 AM
try {
final Element e = elementDao.get(id); // NOPMD by wildi on 9/21/10
// 6:35 AM
final Modification h = e.getLastModification(); // NOPMD by wildi on
// 9/21/10 6:37 AM
return h.getRevision(); // NOPMD by wildi on 9/21/10 6:27 AM
} catch (CoreException e) {
// ToDO, PMD:AvoidPrintStackTrace
e.printStackTrace();
}
return null;
}
// ToDo, PMD:LooseCoupling
@SuppressWarnings({ "unchecked", "rawtypes" })
@Transactional(readOnly = true)
public List findDomainObjectsByArgs(final Class beanClass,
final Map<String, String> args,
final Map<String, Map<String, String>> childargs) throws ElementCreationException {
final List objectsList = new ArrayList();
try {
logger.debug("searching elements {}",
beanClass.getCanonicalName());
final List<Element> elements = elementDao.findElementsByArgs(
beanClass.getCanonicalName(), args, childargs);
logger.debug("Total {} of {}", elements.size(),
beanClass.getCanonicalName());
for (Element e : elements) {
// only elements of beanClass:
if (logger.isDebugEnabled()) {
e.print(0, "about to create object");
}
objectsList.add(load(e.getId()));
}
} catch (SecurityException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:39
// AM
} catch (IllegalArgumentException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:39
// AM
} catch (CoreException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:40
// AM
}
return objectsList;
}
@SuppressWarnings("rawtypes")
public List getAllElementsByPropertyValue(final Class beanClass,
final String prop, final String val) {
List<Element> elements = elementDao
.findByTypeAndPropertyTypeAndStringLike(
beanClass.getCanonicalName(), prop, val);
return elements;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Transactional(readOnly = true)
public List getAllObjectsByPropertyValue(final Class beanClass,
final String prop, final String val) throws ElementCreationException { // NOPMD
// by
// wildi
// on
// 9/21/10
// 6:37
// AM
final List objectsList = new ArrayList();
try {
logger.debug("searching elements {} by prop {} = {}", new Object[] {
beanClass.getCanonicalName(), prop, val });
final List<Element> elements = getAllElementsByPropertyValue(
beanClass, prop, val);
logger.debug("Total {} of {}", elements.size(),
beanClass.getCanonicalName());
for (Element e : elements) {
// only elements of beanClass:
if (logger.isDebugEnabled()) {
e.print(0, "about to create object");
}
objectsList.add(load(e.getId()));
}
} catch (SecurityException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:40
// AM
} catch (IllegalArgumentException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:40
// AM
} catch (CoreException e) {
throw new ElementCreationException(e.getMessage()); // NOPMD by
// wildi on
// 9/21/10 6:41
// AM
}
return objectsList;
}
@SuppressWarnings("rawtypes")
@Transactional(readOnly = true)
public int getCountOfObjectsByPropertyValue(final Class beanClass,
final String prop, final String value) {
return elementDao.getCountByTypeAndPropertyTypeAndStringLike(
beanClass.getCanonicalName(), prop, value);
}
@SuppressWarnings("rawtypes")
@Transactional(readOnly = true)
public int getCountOfObjectsBy2PropertyValues(final Class beanClass,
final String prop1, final String value1, final String prop2,
final String value2) {
return elementDao.getCountByTypeAnd2PropertyTypesAndStringsLike(
beanClass.getCanonicalName(), prop1, value1, prop2, value2);
}
// ToDo, PMD:LooseCoupling
@SuppressWarnings("rawtypes")
@Transactional(readOnly = true)
public int getCountDomainObjectsByArgs(final Class beanClass,
final Map<String, String> args,
final Map<String, Map<String, String>> childargs) {
// false positive, FB: DLS_DEAD_LOCAL_STORE
List objectsList = new ArrayList();
objectsList = elementDao.findElementsByArgs(
beanClass.getCanonicalName(), args, childargs);
return objectsList.size();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public List getAllObjectsByReference(final Class beanClass,
final Object ref)
throws ElementCreationException {
final List objectsList = new ArrayList();
try {
logger.debug("searching elements {} with ",
beanClass.getCanonicalName());
final ElementCreator creator = new ElementCreator(elementTypeDao,
elementDao, propertyTypeDao, null);
final Element eref = creator.create(ref, null);
for (Element e : elementDao.findByTypeAndReference(
beanClass.getCanonicalName(), eref)) {
// only elements of beanClass:
objectsList.add(load(e.getId()));
}
} catch (SecurityException e) {
throw new ElementCreationException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new ElementCreationException(e.getMessage());
} catch (CoreException e) {
throw new ElementCreationException(e.getMessage());
}
return objectsList;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Transactional(readOnly = true)
// TODO: should use db query!!
public List getAllObjects(final Class beanClass) throws ElementCreationException {
final List objectsList = new ArrayList();
try {
logger.debug("searching elements {}",
beanClass.getCanonicalName());
for (Element e : elementDao
.findByType(beanClass.getCanonicalName())) {
// only elements of beanClass:
objectsList.add(load(e.getId()));
}
} catch (SecurityException e) {
throw new ElementCreationException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new ElementCreationException(e.getMessage());
} catch (CoreException e) {
throw new ElementCreationException(e.getMessage());
}
return objectsList;
}
public void setElementDao(final ElementDao elementDao) {
this.elementDao = elementDao;
}
public void setElementTypeDao(final ElementTypeDao elementTypeDao) {
this.elementTypeDao = elementTypeDao;
}
public void setPropertyTypeDao(final PropertyTypeDao propertyTypeDao) {
this.propertyTypeDao = propertyTypeDao;
}
@Transactional(readOnly = true)
public PropertyType getPropertyType(final String name) throws CoreException {
return propertyTypeDao.findByName(name);
}
@Transactional(readOnly = true)
public List<ElementType> getAllElementsTypes() {
return elementTypeDao.getAll();
}
@Transactional
public void delete(final Long id) throws CoreException {
Element e = elementDao.get(id);
if( e!=null ){
e.setStateDeleted();
elementDao.save(e);
}
}
@Transactional(readOnly = true)
public Element getElement(Long id) {
return elementDao.get(id);
}
public void activateCaching(boolean flag){
this.useCache=flag;
}
public net.sf.ehcache.Statistics getCacheStatistics() {
return cache.getStatistics();
}
}