/** * 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.rulebase.filebackend; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.openengsb.core.api.model.ConfigItem; import org.openengsb.core.api.persistence.ConfigPersistenceBackendService; import org.openengsb.core.api.persistence.InvalidConfigurationException; import org.openengsb.core.api.persistence.PersistenceException; import org.openengsb.core.workflow.drools.model.GlobalConfiguration; import org.openengsb.core.workflow.drools.model.GlobalDeclaration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; /** * A backend implementation for ConfigPersistence that saves GlobalDeclaration objects to file. */ public class GlobalDeclarationPersistenceBackendService implements ConfigPersistenceBackendService<GlobalDeclaration> { private File storageFile; private static final Logger LOGGER = LoggerFactory.getLogger(GlobalDeclarationPersistenceBackendService.class); private static final String SEPARATOR = " "; public void setStorageFilePath(String storageFilePath) { storageFile = new File(storageFilePath); } @Override public List<ConfigItem<GlobalDeclaration>> load(Map<String, String> metadata) throws PersistenceException, InvalidConfigurationException { List<ConfigItem<GlobalDeclaration>> ret; LOGGER.debug("loading GlobalDeclaration Configuration"); if (storageFile.exists()) { if (metadata.get(GlobalDeclaration.META_GLOBAL_VARIABLE) != null) { ret = loadSingleGlobal(metadata.get(GlobalDeclaration.META_GLOBAL_VARIABLE)); } else { ret = loadAllGlobals(); } } else { LOGGER.debug( "Can't load configuration, because \"{}\" doesn't exist. Returning default empty list!", storageFile); ret = new ArrayList<ConfigItem<GlobalDeclaration>>(); } return ret; } @SuppressWarnings("unchecked") @Override public void persist(ConfigItem<GlobalDeclaration> config) throws PersistenceException, InvalidConfigurationException { LOGGER.debug("persisting global \"{}\"", config.getContent().getVariableName()); Preconditions.checkArgument(supports((Class<? extends ConfigItem<?>>) config.getClass()), "Argument type not supported"); Map<String, String> globals = readStorageFile(); GlobalDeclaration global = config.getContent(); globals.put(global.getVariableName(), global.getClassName()); writeStorageFile(globals); } @Override public void remove(Map<String, String> metadata) throws PersistenceException { LOGGER.debug("removing global"); Preconditions.checkNotNull(metadata.get(GlobalDeclaration.META_GLOBAL_VARIABLE), "Variable name has to be defined"); Map<String, String> globals = readStorageFile(); String variableName = metadata.get(GlobalDeclaration.META_GLOBAL_VARIABLE); if (!globals.containsKey(variableName)) { LOGGER.warn("Couldn't remove global \"{}\", because it does not exist in \"{}\"", variableName, storageFile); } else { globals.remove(variableName); writeStorageFile(globals); } } @Override public boolean supports(Class<? extends ConfigItem<?>> configItemType) { return GlobalConfiguration.class.isAssignableFrom(configItemType); } private Map<String, String> readStorageFile() throws PersistenceException { LOGGER.debug("try to read \"{}\"", storageFile); Map<String, String> ret = new HashMap<String, String>(); List<String> lines; if (storageFile.exists()) { try { lines = FileUtils.readLines(storageFile); } catch (IOException e) { LOGGER.error("Error reading \"{}\"", storageFile); throw new PersistenceException(e); } for (String line : lines) { if (!line.equals("")) { String[] splitLine = line.split(SEPARATOR); ret.put(splitLine[1], splitLine[0]); } } } return ret; } private List<ConfigItem<GlobalDeclaration>> loadSingleGlobal(String variableName) throws PersistenceException { LOGGER.debug("Load single global \"{}\"", variableName); List<ConfigItem<GlobalDeclaration>> ret = new ArrayList<ConfigItem<GlobalDeclaration>>(); Map<String, String> globals = readStorageFile(); if (globals.containsKey(variableName)) { String className = globals.get(variableName); GlobalDeclaration global = new GlobalDeclaration(className, variableName); GlobalConfiguration cnf = new GlobalConfiguration(global.toMetadata(), global); ret.add(cnf); } return ret; } private List<ConfigItem<GlobalDeclaration>> loadAllGlobals() throws PersistenceException { LOGGER.debug("Load all globals"); List<ConfigItem<GlobalDeclaration>> ret = new ArrayList<ConfigItem<GlobalDeclaration>>(); Map<String, String> globals = readStorageFile(); for (Entry<String, String> entry : globals.entrySet()) { GlobalDeclaration global = new GlobalDeclaration(entry.getValue(), entry.getKey()); GlobalConfiguration cnf = new GlobalConfiguration(global.toMetadata(), global); ret.add(cnf); } return ret; } private void writeStorageFile(Map<String, String> globals) throws PersistenceException { LOGGER.debug("write globals to \"{}\"", storageFile); OutputStream os = null; try { os = FileUtils.openOutputStream(storageFile); for (Entry<String, String> entry : globals.entrySet()) { IOUtils.write( entry.getValue() + SEPARATOR + entry.getKey() + IOUtils.LINE_SEPARATOR, os); } } catch (IOException ex) { throw new PersistenceException(ex); } finally { IOUtils.closeQuietly(os); } } }