/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI licenses this file to you 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 org.openengsb.persistence.connector.jpabackend;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.openengsb.core.api.Constants;
import org.openengsb.core.api.model.ConfigItem;
import org.openengsb.core.api.model.ConnectorConfiguration;
import org.openengsb.core.api.model.ConnectorDescription;
import org.openengsb.core.api.persistence.ConfigPersistenceBackendService;
import org.openengsb.core.api.persistence.InvalidConfigurationException;
import org.openengsb.core.api.persistence.PersistenceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
/**
* The ConnectorJPAPersistenceBackendService is a ConfigPersistence implementation
* used to store ConnectorDescription objects to database via JPA.
*
*/
public class ConnectorJPAPersistenceBackendService implements
ConfigPersistenceBackendService<ConnectorDescription> {
private static final Logger LOGGER = LoggerFactory
.getLogger(ConnectorJPAPersistenceBackendService.class);
private EntityManager entityManager;
@Override
public List<ConfigItem<ConnectorDescription>> load(
Map<String, String> metadata) throws PersistenceException,
InvalidConfigurationException {
LOGGER.debug("load ConnectorConfiguration");
List<ConnectorConfigurationJPAEntity> entities = searchForMetadata(metadata);
List<ConfigItem<ConnectorDescription>> ret = new ArrayList<ConfigItem<ConnectorDescription>>();
for (ConnectorConfigurationJPAEntity entity : entities) {
ret.add(ConnectorConfigurationJPAEntity.toConfigItem(entity));
}
return ret;
}
@SuppressWarnings("unchecked")
@Override
public void persist(ConfigItem<ConnectorDescription> config)
throws PersistenceException, InvalidConfigurationException {
LOGGER.debug("persisting ConnectorConfiguration");
Preconditions.checkArgument(
supports((Class<? extends ConfigItem<?>>) config.getClass()),
"Argument type not supported");
Preconditions.checkNotNull(config, "Config must not be null");
Preconditions.checkNotNull(config.getMetaData().get(Constants.CONNECTOR_PERSISTENT_ID),
"No id set!");
Preconditions.checkNotNull(config.getContent(), "Invalid content");
List<ConnectorConfigurationJPAEntity> oldEntities = searchForMetadata(config
.getMetaData());
if (oldEntities.size() > 1) {
throw new PersistenceException(
"Unexpected error: Found more than 1 object fitting the metadata!");
}
ConnectorConfigurationJPAEntity entity = ConnectorConfigurationJPAEntity
.generateFromConfigItem(config);
if (oldEntities.size() == 1) {
ConnectorConfigurationJPAEntity old = oldEntities.get(0);
old.setConnectorType(entity.getConnectorType());
old.setDomainType(entity.getDomainType());
old.setAttributes(entity.getAttributes());
old.setProperties(entity.getProperties());
try {
synchronized (entityManager) {
entityManager.merge(old);
}
} catch (Exception ex) {
throw new PersistenceException(ex);
}
LOGGER.info("updated ConnectorConfiguration");
} else {
try {
synchronized (entityManager) {
entityManager.persist(entity);
}
} catch (Exception ex) {
throw new PersistenceException(ex);
}
LOGGER.info("inserted ConnectorConfiguration");
}
}
@Override
public void remove(Map<String, String> metadata)
throws PersistenceException {
LOGGER.debug("removing ConnectorConfiguration");
Preconditions.checkNotNull(metadata, "Invalid metadata");
Preconditions
.checkNotNull(metadata.get(Constants.CONNECTOR_PERSISTENT_ID), "No Id set!");
List<ConnectorConfigurationJPAEntity> ret = searchForMetadata(metadata);
if (ret.size() == 0) {
throw new PersistenceException(
"Configuration to delete could not be found!");
}
synchronized (entityManager) {
for (ConnectorConfigurationJPAEntity entity : ret) {
try {
entityManager.remove(entity);
} catch (Exception ex) {
throw new PersistenceException(ex);
}
}
}
LOGGER.info("removed ConnectorConfiguration");
}
@Override
public boolean supports(Class<? extends ConfigItem<?>> configItemType) {
return ConnectorConfiguration.class.isAssignableFrom(configItemType);
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
private List<ConnectorConfigurationJPAEntity> searchForMetadata(
Map<String, String> metaData) throws PersistenceException {
synchronized (entityManager) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ConnectorConfigurationJPAEntity> query = cb
.createQuery(ConnectorConfigurationJPAEntity.class);
Root<ConnectorConfigurationJPAEntity> from = query
.from(ConnectorConfigurationJPAEntity.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (metaData.get(Constants.CONNECTOR_PERSISTENT_ID) != null) {
predicates.add(cb.equal(from.get("instanceId"),
metaData.get(Constants.CONNECTOR_PERSISTENT_ID)));
}
query.select(from);
query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
try {
return entityManager.createQuery(query).getResultList();
} catch (Exception ex) {
throw new PersistenceException(ex);
}
}
}
}