/** * Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * - Apache License, version 2.0 * - Apache Software License, version 1.0 * - GNU Lesser General Public License, version 3 * - Mozilla Public License, versions 1.0, 1.1 and 2.0 * - Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * License version 2 and the aforementioned licenses. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ package org.n52.sos.utils; import org.n52.sos.config.SettingsManager; import org.n52.sos.config.annotation.Configurable; import org.n52.sos.config.annotation.Setting; import org.n52.sos.exi.EXISettings; import org.n52.sos.ogc.sos.Sos1Constants; import org.n52.sos.ogc.sos.Sos2Constants; import org.n52.sos.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.siemens.ct.exi.CodingMode; import com.siemens.ct.exi.EXIFactory; import com.siemens.ct.exi.FidelityOptions; import com.siemens.ct.exi.GrammarFactory; import com.siemens.ct.exi.exceptions.EXIException; import com.siemens.ct.exi.exceptions.UnsupportedOption; import com.siemens.ct.exi.grammars.Grammars; import com.siemens.ct.exi.helpers.DefaultEXIFactory; /** * TODO JavaDoc * * @author Eike Hinderk Jürrens <e.h.juerrens@52north.org> * @since 4.2.0 */ @Configurable public class EXIUtils { private static final Logger LOGGER = LoggerFactory.getLogger(EXIUtils.class); private static Grammars GRAMMAR_SOS20 = null; private static Grammars GRAMMAR_SOS10 = null; private static Grammars GRAMMAR_BASETYPES = null; private CodingMode alignment = CodingMode.BIT_PACKED; private boolean isStrict; private boolean isDefault; private boolean preserveComments; private boolean preserveProcessingInstructions; private boolean preserveDTD; private boolean preservePrefixes; private boolean preserveLexicalValue; private static boolean isSchemaLessGrammar; private static boolean isXSBaseTypeGrammar; private static boolean isSOS20Schema; private static boolean isSOS10Schema; private static EXIUtils instance = null; private EXIUtils() { } public static synchronized EXIUtils getInstance() { if (instance == null) { instance = new EXIUtils(); SettingsManager.getInstance().configure(instance); try { // Pre-load Grammars from URL to save time // TODO does this result in any race conditions? if (!isSchemaLessGrammar()) { if (isXSBaseTypeGrammar()) { GRAMMAR_BASETYPES = GrammarFactory.newInstance().createXSDTypesOnlyGrammars(); } else if (isSOS10Schema()) { GRAMMAR_SOS10 = GrammarFactory.newInstance().createGrammars(Sos1Constants.SCHEMA_LOCATION_SOS); } else if (isSOS20Schema()) { GRAMMAR_SOS20 = GrammarFactory.newInstance().createGrammars(Sos2Constants.SCHEMA_LOCATION_URL_SOS); } } } catch (EXIException e) { LOGGER.error("Could not load XSD schema for EXI binding. " + "Using default schema less grammar. Please update your settings.", e); } } return instance; } @Setting(EXISettings.EXI_FIDELITY_LEXICAL_VALUE) public void setFidelityLexicalValue(final boolean preserveLexicalValue) { this.preserveLexicalValue = preserveLexicalValue; } @Setting(EXISettings.EXI_FIDELITY_PREFIXES) public void setFidelityPrefixes(final boolean preservePrefixes) { this.preservePrefixes = preservePrefixes; } @Setting(EXISettings.EXI_FIDELITY_DTD) public void setFidelityDTD(final boolean preserveDTD) { this.preserveDTD = preserveDTD; } @Setting(EXISettings.EXI_FIDELITY_PROCESSING_INSTRUCTIONS) public void setFidelityProcessingInstructions(final boolean preserveProcessingInstructions) { this.preserveProcessingInstructions = preserveProcessingInstructions; } @Setting(EXISettings.EXI_FIDELITY_COMMENTS) public void setFidelityComments(final boolean preserveComments) { this.preserveComments = preserveComments; } @Setting(EXISettings.EXI_FIDELITY) public void setStrictFidelity(final String fidelity) { Validation.notNullOrEmpty(EXISettings.EXI_FIDELITY, fidelity); if (fidelity.equalsIgnoreCase(EXISettings.EXI_FIDELITY_STRICT)) { this.isStrict = true; } else if (fidelity.equalsIgnoreCase(EXISettings.EXI_FIDELITY_DEFAULT)) { this.isDefault = true; } } @Setting(EXISettings.EXI_ALIGNMENT) public void setCodingMode(final String codingMode) { Validation.notNullOrEmpty(EXISettings.EXI_ALIGNMENT, codingMode); this.alignment = CodingMode.valueOf(codingMode); } @Setting(EXISettings.EXI_GRAMMAR) public void setGrammarType(final String grammar) { Validation.notNullOrEmpty(EXISettings.EXI_GRAMMAR, grammar); if (grammar.equalsIgnoreCase(EXISettings.EXI_GRAMMAR_SCHEMALESS)) { setSchemaLessGrammar(true); } else if (grammar.equalsIgnoreCase(EXISettings.EXI_GRAMMAR_BASETYPES)) { setXSBaseTypeGrammar(true); } } @Setting(EXISettings.EXI_GRAMMAR_SCHEMA) public void setGrammarSchema(final String grammarSchema) { Validation.notNullOrEmpty(EXISettings.EXI_GRAMMAR_SCHEMA, grammarSchema); if (grammarSchema.equalsIgnoreCase(EXISettings.EXI_GRAMMAR_SCHEMA_SOS_20)) { setSOS20Schema(true); } else if (grammarSchema.equalsIgnoreCase(EXISettings.EXI_GRAMMAR_SCHEMA_SOS_10)) { setSOS10Schema(true); } } /** * @return the isSchemaLessGrammar */ private static boolean isSchemaLessGrammar() { return isSchemaLessGrammar; } /** * @param isSchemaLessGrammar the isSchemaLessGrammar to set */ private static void setSchemaLessGrammar(boolean isSchemaLessGrammar) { EXIUtils.isSchemaLessGrammar = isSchemaLessGrammar; } /** * @return the isXSBaseTypeGrammar */ public static boolean isXSBaseTypeGrammar() { return isXSBaseTypeGrammar; } /** * @param isXSBaseTypeGrammar the isXSBaseTypeGrammar to set */ public static void setXSBaseTypeGrammar(boolean isXSBaseTypeGrammar) { EXIUtils.isXSBaseTypeGrammar = isXSBaseTypeGrammar; } /** * @return the isSOS20Schema */ public static boolean isSOS20Schema() { return isSOS20Schema; } /** * @param isSOS20Schema the isSOS20Schema to set */ public static void setSOS20Schema(boolean isSOS20Schema) { EXIUtils.isSOS20Schema = isSOS20Schema; } /** * @return the isSOS10Schema */ public static boolean isSOS10Schema() { return isSOS10Schema; } /** * @param isSOS10Schema the isSOS10Schema to set */ public static void setSOS10Schema(boolean isSOS10Schema) { EXIUtils.isSOS10Schema = isSOS10Schema; } /** * @return An {@link EXIFactory} instance configured according the service * configuration. * @throws UnsupportedOption * if one of the fidelity options is not supported. */ public EXIFactory newEXIFactory() throws UnsupportedOption { EXIFactory ef = DefaultEXIFactory.newInstance(); // // GRAMMAR // // TODO How to identify the correct location: SOS 1.0 vs. 2.0 vs WFS vs // WPS ... Grammars g = null; if (!isSchemaLessGrammar()) { if (isXSBaseTypeGrammar()) { g = GRAMMAR_BASETYPES; } else { if (isSOS20Schema()) { g = GRAMMAR_SOS20; } else if (isSOS10Schema()) { g = GRAMMAR_SOS10; } } } // default to schema less grammar if (g == null) { g = GrammarFactory.newInstance().createSchemaLessGrammars(); } ef.setGrammars(g); // // STRICT vs. OTHER fidelity options // // TODO is it possible to identify these options via any EXI header or // something else? if (isStrict) { ef.setFidelityOptions(FidelityOptions.createStrict()); } else if (isDefault) { ef.setFidelityOptions(FidelityOptions.createDefault()); } else { if (preserveComments) { ef.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_COMMENT, true); } if (preserveProcessingInstructions) { ef.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_PI, true); } if (preserveDTD) { ef.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_DTD, true); } if (preservePrefixes) { ef.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_PREFIX, true); } if (preserveLexicalValue) { ef.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_LEXICAL_VALUE, true); } } ef.setCodingMode(alignment); // // TODO Implement usage and settings UI for Additional Values // // ef.setValueMaxLength(ANY_CONSTANT_OR_SETTING); // ef.setValuePartitionCapacity(ANY_CONSTANT_OR_SETTING); // if (cm.usesRechanneling()) { // ef.setBlockSize(ANY_CONSTANT_OR_SETTING); // } return ef; } }