/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is part of dcm4che, an implementation of DICOM(TM) in * Java(TM), hosted at https://github.com/gunterze/dcm4che. * * The Initial Developer of the Original Code is * Agfa Healthcare. * Portions created by the Initial Developer are Copyright (C) 2011-2014 * the Initial Developer. All Rights Reserved. * * Contributor(s): * See @authors listed below * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.dcm4che3.conf.dicom; import org.dcm4che3.conf.ConfigurationSettingsLoader; import org.dcm4che3.conf.core.DefaultBeanVitalizer; import org.dcm4che3.conf.core.ExtensionMergingConfiguration; import org.dcm4che3.conf.core.api.Configuration; import org.dcm4che3.conf.core.api.ConfigurationException; import org.dcm4che3.conf.core.api.Path; import org.dcm4che3.conf.core.index.ReferenceIndexingDecorator; import org.dcm4che3.conf.core.normalization.DefaultsAndNullFilterDecorator; import org.dcm4che3.conf.core.olock.HashBasedOptimisticLockingConfiguration; import org.dcm4che3.conf.core.storage.SimpleCachingConfigurationDecorator; import org.dcm4che3.conf.core.storage.SingleJsonFileConfigurationStorage; import org.dcm4che3.net.AEExtension; import org.dcm4che3.net.DeviceExtension; import org.dcm4che3.net.hl7.HL7ApplicationExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; /** * @author Gunter Zeilinger <gunterze@gmail.com> */ public class DicomConfigurationBuilder { private Hashtable<?, ?> props; private static Logger LOG = LoggerFactory .getLogger(DicomConfigurationBuilder.class); private boolean extensionMerge = false; private boolean cache = false; private Hashtable<?, ?> ldapProps = null; private Configuration configurationStorage = null; private Map<Class, List<Class>> extensionClassesMap = new HashMap<Class, List<Class>>(); private boolean doOptimisticLocking = false; private boolean uuidIndexing = true; private void setLdapProps(Hashtable<?, ?> ldapProps) { this.ldapProps = ldapProps; } public DicomConfigurationBuilder() { this.props = new Hashtable<Object, Object>(); } public DicomConfigurationBuilder(Hashtable<?, ?> props) { this.props = props; } public DicomConfigurationBuilder registerCustomConfigurationStorage(Configuration storage) { configurationStorage = storage; return this; } public DicomConfigurationBuilder registerExtensionForBaseExtension(Class extensionClass, Class baseExtensionClass) { List<Class> extensionClasses = extensionClassesMap.get(baseExtensionClass); if (extensionClasses == null) { extensionClasses = new ArrayList<Class>(); extensionClassesMap.put(baseExtensionClass, extensionClasses); } // don't put duplicates if (!extensionClasses.contains(extensionClass)) extensionClasses.add(extensionClass); return this; } public <T extends DeviceExtension> DicomConfigurationBuilder registerDeviceExtension( Class<T> clazz) { registerExtensionForBaseExtension(clazz, DeviceExtension.class); return this; } public <T extends AEExtension> DicomConfigurationBuilder registerAEExtension( Class<T> clazz) { registerExtensionForBaseExtension(clazz, AEExtension.class); return this; } public <T extends HL7ApplicationExtension> DicomConfigurationBuilder registerHL7ApplicationExtension( Class<T> clazz) { registerExtensionForBaseExtension(clazz, HL7ApplicationExtension.class); return this; } public DicomConfigurationBuilder extensionMerge(boolean extensionMerge) { this.extensionMerge = extensionMerge; return this; } public DicomConfigurationBuilder cache(boolean cache) { this.cache = cache; return this; } public DicomConfigurationBuilder uuidIndexing() { this.uuidIndexing = true; return this; } public DicomConfigurationBuilder disableUuidIndexing() { this.uuidIndexing = false; return this; } public CommonDicomConfigurationWithHL7 build() throws ConfigurationException { List<Class> allExtensions = new ArrayList<Class>(); for (Map.Entry<Class, List<Class>> classListEntry : extensionClassesMap.entrySet()) allExtensions.addAll(classListEntry.getValue()); Configuration configurationStorage = createConfigurationStorage(allExtensions); if (configurationStorage == null) return null; for (Map.Entry<Class, List<Class>> classListEntry : extensionClassesMap.entrySet()) LOG.info("Dcm4che configuration {} classes: {}", classListEntry.getKey().getSimpleName(), classListEntry.getValue()); // check if we have any extensions that have equal simple name and fail if found HashSet<String> simpleNames = new HashSet<String>(); for (Class extension : allExtensions) { if (!simpleNames.add(extension.getSimpleName())) throw new ConfigurationException( "Duplicate configuration class extension name '" + extension.getSimpleName() + "'. Make sure that simple class names of extensions are unique!"); } return new CommonDicomConfigurationWithHL7(configurationStorage, extensionClassesMap); } protected Configuration createConfigurationStorage(List<Class> allExtensions) throws ConfigurationException { // if configurationStorage is already set - skip the storage init if (configurationStorage == null) { String configType = ConfigurationSettingsLoader.getPropertyWithNotice(props, Configuration.CONF_STORAGE_SYSTEM_PROP, "json_file", " Possible values: 'json_file'."); switch (Configuration.ConfigStorageType.valueOf(configType.toUpperCase().trim())) { case JSON_FILE: SingleJsonFileConfigurationStorage jsonConfigurationStorage = createJsonFileConfigurationStorage(); jsonConfigurationStorage.configure(props); configurationStorage = jsonConfigurationStorage; break; default: throw new RuntimeException("Not implemented"); } } if (cache) configurationStorage = new SimpleCachingConfigurationDecorator(configurationStorage, props); if(extensionMerge) configurationStorage = new ExtensionMergingConfiguration(configurationStorage, allExtensions); if (uuidIndexing) configurationStorage = new ReferenceIndexingDecorator(configurationStorage, new HashMap<String, Path>()); if (doOptimisticLocking) configurationStorage = new HashBasedOptimisticLockingConfiguration(configurationStorage, allExtensions); configurationStorage = new DefaultsAndNullFilterDecorator( configurationStorage, allExtensions, CommonDicomConfiguration.createDefaultDicomVitalizer() ); return configurationStorage; } protected SingleJsonFileConfigurationStorage createJsonFileConfigurationStorage() { return new SingleJsonFileConfigurationStorage(); } public static DicomConfigurationBuilder newConfigurationBuilder(Hashtable<?, ?> props) throws ConfigurationException { return new DicomConfigurationBuilder(props); } public static DicomConfigurationBuilder newJsonConfigurationBuilder(String fileName) { Hashtable<Object, Object> props = new Hashtable<Object, Object>(); props.put("org.dcm4che.conf.storage", "json_file"); props.put("org.dcm4che.conf.filename", fileName); return new DicomConfigurationBuilder(props); } @Deprecated public static DicomConfigurationBuilder newLdapConfigurationBuilder(Hashtable<?, ?> ldapProps) throws ConfigurationException { Hashtable<Object, Object> props = new Hashtable<Object, Object>(); props.put("org.dcm4che.conf.storage", "ldap"); DicomConfigurationBuilder dicomConfigurationBuilder = new DicomConfigurationBuilder(props); dicomConfigurationBuilder.setLdapProps(ldapProps); return dicomConfigurationBuilder; } public DicomConfigurationBuilder optimisticLocking(boolean doOptimisticLocking) { this.doOptimisticLocking = doOptimisticLocking; return this; } }