AT&T 2.0.19 Code drop, stage 1
Issue-ID: AAF-197
Change-Id: Ie75c6c322e9c4e7982b198cb48439e926c3a1fbd
Signed-off-by: Instrumental <jcgmisc@stl.gathman.org>
diff --git a/misc/.gitignore b/misc/.gitignore
new file mode 100644
index 0000000..0c2b833
--- /dev/null
+++ b/misc/.gitignore
@@ -0,0 +1,2 @@
+/.settings/
+/.project
diff --git a/misc/env/.gitignore b/misc/env/.gitignore
new file mode 100644
index 0000000..51037e6
--- /dev/null
+++ b/misc/env/.gitignore
@@ -0,0 +1,5 @@
+/target/
+/.classpath
+/.settings/
+/target/
+/.project
diff --git a/misc/env/pom.xml b/misc/env/pom.xml
new file mode 100644
index 0000000..e724f8e
--- /dev/null
+++ b/misc/env/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aaf-misc-env</artifactId>
+ <name>AAF Misc Env</name>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>compile</scope> <!-- Provides scope only, in case other users prefer another Logging Implementation -->
+ </dependency>
+ </dependencies>
+</project>
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/APIException.java b/misc/env/src/main/java/org/onap/aaf/misc/env/APIException.java
new file mode 100644
index 0000000..2b66345
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/APIException.java
@@ -0,0 +1,89 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+/**
+ * An Exception with the ability to hold a payload.<p>
+ *
+ * This is important, because sometimes, the output of a Framework
+ * may be a descriptive object which doesn't inherit from Throwable
+ * and thus cannot be attached in "initCause".<p>
+ *
+ * Examples may be a SOAP Fault.
+ *
+ * @author Jonathan
+ *
+ */
+public class APIException extends Exception {
+
+ private Object payload = null;
+
+ /**
+ * @param t
+ */
+ public APIException(Throwable t) {
+ super(t);
+ }
+
+ /**
+ * @param string
+ */
+ public APIException(String string) {
+ super(string);
+ }
+
+ /**
+ * @param errorMessage
+ * @param t
+ */
+ public APIException(String errorMessage, Throwable t) {
+ super(errorMessage,t);
+ }
+
+ /**
+ * Return payload, or null if none was set. Type is up to the calling
+ * System.
+ *
+ * @return Object
+ */
+ public Object getPayload() {
+ return payload;
+ }
+
+ /**
+ * Set a specific payload into this Exception, which doesn't necessarily
+ * inherit from Throwable.
+ *
+ * @param payload
+ * @return APIException
+ */
+ public APIException setPayload(Object payload) {
+ this.payload = payload;
+ return this;
+ }
+
+ /**
+ * Java expected serial ID
+ */
+ private static final long serialVersionUID = 3505343458251445169L;
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/BaseDataFactory.java b/misc/env/src/main/java/org/onap/aaf/misc/env/BaseDataFactory.java
new file mode 100644
index 0000000..4750b3e
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/BaseDataFactory.java
@@ -0,0 +1,478 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.onap.aaf.misc.env.impl.EnvFactory;
+import org.xml.sax.SAXException;
+
+
+
+/**
+ * DataFactory Constructor will create the Stringifiers and Objectifiers necessary
+ * by Type and store the Class of the Type for quick creation of Data Objects
+ * with reused (and thread safe) components
+ * s
+ * Native Types are included.
+ * Those types covered by Env Implementation are covered dynamically.
+ * Types outside of Env mechanism can be added with "add" function
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public class BaseDataFactory {
+
+ /**
+ * Generate a Schema Object for use in validation based on FileNames.
+ *
+ * WARNING: The java.xml.binding code requires YOU to figure out what order the
+ * files go in. If there is an import from A in B, then you must list A first.
+ *
+ * @param err
+ * @param filenames
+ * @return
+ * @throws APIException
+ */
+ public static Schema genSchema(Store env, String ... filenames) throws APIException {
+ String schemaDir = env.get(
+ env.staticSlot(EnvFactory.SCHEMA_DIR),
+ EnvFactory.DEFAULT_SCHEMA_DIR);
+ File dir = new File(schemaDir);
+ if(!dir.exists())throw new APIException("Schema Directory " + schemaDir + " does not exist. You can set this with " + EnvFactory.SCHEMA_DIR + " property");
+ FileInputStream[] fis = new FileInputStream[filenames.length];
+ Source[] sources = new Source[filenames.length];
+ File f;
+ for(int i=0; i<filenames.length; ++i) {
+ if(!(f=new File(schemaDir + File.separatorChar + filenames[i])).exists()) {
+ if(!f.exists()) throw new APIException("Cannot find " + f.getName() + " for schema validation");
+ }
+ try {
+ fis[i]=new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ throw new APIException(e);
+ }
+ sources[i]= new StreamSource(fis[i]);
+ }
+ try {
+ //Note: SchemaFactory is not reentrant or very thread safe either... see docs
+ synchronized(XMLConstants.W3C_XML_SCHEMA_NS_URI) { // SchemaFactory is not reentrant
+ return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
+ .newSchema(sources);
+ }
+ } catch (SAXException e) {
+ throw new APIException(e);
+ } finally {
+ for(FileInputStream d : fis) {
+ try {
+ d.close();
+ } catch (IOException e) {
+ // Never mind... we did our best
+ }
+ }
+ }
+
+ }
+
+ public static QName getQName(Class<?> clss) throws APIException {
+ // Obtain the Necessary info for QName from Requirement
+ XmlRootElement xre = clss.getAnnotation(XmlRootElement.class);
+ if(xre==null)throw new APIException(clss.getName() + " does not have an XmlRootElement annotation");
+ Package pkg = clss.getPackage();
+ XmlSchema xs = pkg.getAnnotation(XmlSchema.class);
+ if(xs==null) throw new APIException(clss.getName() + " package-info does not have an XmlSchema annotation");
+ return new QName(xs.namespace(),xre.name());
+ }
+
+ /////////////////////////////////////////////
+ // Native Type Converters
+ /////////////////////////////////////////////
+// /**
+// * StringStringifier
+// *
+// * Support the Native Type String.. just return it back
+// *
+// * @author Jonathan
+// *
+// */
+// public static class StringStringifier extends NullLifeCycle implements Stringifier<String> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, String input) throws APIException {
+// return input;
+// }
+// };
+//
+// /**
+// * StringObjectifier
+// *
+// * Support the Native Type String.. just return it back
+// *
+// * @author Jonathan
+// *
+// */
+// public static class StringObjectifier extends NullLifeCycle implements Objectifier<String> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public String objectify(Env env, String input) throws APIException {
+// return input;
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public String newInstance() throws APIException {
+// return "";
+// }
+// };
+//
+// /**
+// * LongStringifier
+// *
+// * Support the Native Type Long.. use Long parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class LongStringifier extends NullLifeCycle implements Stringifier<Long> {
+// public String stringify(Env env, Long input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * LongObjectifier
+// *
+// * Support the Native Type Long.. use Long parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class LongObjectifier extends NullLifeCycle implements Objectifier<Long> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Long objectify(Env env, String input) throws APIException {
+// try {
+// return new Long(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Long\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Long newInstance() throws APIException {
+// return 0L;
+// }
+// }
+//
+// /**
+// * IntegerStringifier
+// *
+// * Support the Native Integer.. use Integer parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class IntegerStringifier extends NullLifeCycle implements Stringifier<Integer> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, Integer input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * IntegerObjectifier
+// *
+// * Support the Native Integer.. use Integer parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class IntegerObjectifier extends NullLifeCycle implements Objectifier<Integer> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Integer objectify(Env env, String input) throws APIException {
+// try {
+// return new Integer(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Integer\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Integer newInstance() throws APIException {
+// return 0;
+// }
+// }
+//
+// /**
+// * ShortStringifier
+// *
+// * Support the Native Short.. use Short parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class ShortStringifier extends NullLifeCycle implements Stringifier<Short> {
+// public String stringify(Env env, Short input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * ShortObjectifier
+// *
+// * Support the Native Short.. use Short parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class ShortObjectifier extends NullLifeCycle implements Objectifier<Short> {
+// public Short objectify(Env env, String input) throws APIException {
+// try {
+// return new Short(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Short\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// public Short newInstance() throws APIException {
+// return 0;
+// }
+// }
+//
+// /**
+// * ByteStringifier
+// *
+// * Support the Native Byte.. use Byte parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class ByteStringifier extends NullLifeCycle implements Stringifier<Byte> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, Byte input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * ByteObjectifier
+// *
+// * Support the Native Byte.. use Byte parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class ByteObjectifier extends NullLifeCycle implements Objectifier<Byte> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Byte objectify(Env env, String input) throws APIException {
+// try {
+// return new Byte(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Byte\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Byte newInstance() throws APIException {
+// return 0;
+// }
+// }
+//
+// /**
+// * CharacterStringifier
+// *
+// * Support the Native Character.. use Character parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class CharacterStringifier extends NullLifeCycle implements Stringifier<Character> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, Character input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * CharacterObjectifier
+// *
+// * Support the Native Character.. use Character parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class CharacterObjectifier extends NullLifeCycle implements Objectifier<Character> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Character objectify(Env env, String input) throws APIException {
+// int length = input.length();
+// if(length<1 || length>1) {
+// throw new APIException("String [" + input + "] does not represent a single Character");
+// }
+// return input.charAt(0);
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Character newInstance() throws APIException {
+// return 0;
+// }
+// }
+//
+// /**
+// * FloatStringifier
+// *
+// * Support the Native Float.. use Float parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class FloatStringifier extends NullLifeCycle implements Stringifier<Float> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, Float input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * FloatObjectifier
+// *
+// * Support the Native Float.. use Float parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class FloatObjectifier extends NullLifeCycle implements Objectifier<Float> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Float objectify(Env env, String input) throws APIException {
+// try {
+// return new Float(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Float\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Float newInstance() throws APIException {
+// return 0.0f;
+// }
+// }
+//
+// /**
+// * DoubleStringifier
+// *
+// * Support the Native Double.. use Double parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class DoubleStringifier extends NullLifeCycle implements Stringifier<Double> {
+// /* (non-Javadoc)
+// * @see com.att.env.Stringifier#stringify(com.att.env.Env, java.lang.Object)
+// */
+// public String stringify(Env env, Double input) throws APIException {
+// return input.toString();
+// }
+// }
+//
+// /**
+// * DoubleObjectifier
+// *
+// * Support the Native Double.. use Double parse functions
+// *
+// * @author Jonathan
+// *
+// */
+// public static class DoubleObjectifier extends NullLifeCycle implements Objectifier<Double> {
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#objectify(com.att.env.Env, java.lang.String)
+// */
+// public Double objectify(Env env, String input) throws APIException {
+// try {
+// return new Double(input);
+// } catch (Exception e) {
+// APIException ae = new APIException("Cannot create a \"Double\" from [" + input + ']');
+// ae.initCause(e);
+// throw ae;
+// }
+// }
+//
+// /* (non-Javadoc)
+// * @see com.att.env.Objectifier#newObject()
+// */
+// public Double newInstance() throws APIException {
+// return 0.0;
+// }
+// }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Creatable.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Creatable.java
new file mode 100644
index 0000000..995819e
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Creatable.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+/**
+ * <h1>Creatable</h1>
+ * <b>**Must implement constructor T(ENV env, long currentTimeMillis);**</b><p>
+ *
+ * This interface exists to cover basic LifeCycle semantics so that Objects
+ * can be created dynamically and managed at a basic level (destroy(env)).
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public interface Creatable<T> {
+ /**
+ * Return the timestamp (Unix long) when this object was created.<p>
+ * This can be used to see if the object is out of date in certain
+ * circumstances, or perhaps has already been notified in others.
+ *
+ * @return long
+ */
+ public abstract long created();
+
+ /**
+ * Allow LifeCycle aware process to signal this element as destroyed.
+ *
+ * @param env
+ */
+ public abstract void destroy(Env env);
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Data.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Data.java
new file mode 100644
index 0000000..2c24cb1
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Data.java
@@ -0,0 +1,113 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+/**
+ * <H1>Data</H1>
+ * <i>Data</i> facilitates lazy marshaling of data with a pre-determined
+ * marshaling mechanism.<p>
+ *
+ * It stores either Object (defined by Generic {@literal <T>}) or String.<p>
+ *
+ * On asking for Object of type {@literal <T>}, it will respond with the object
+ * if it exists, or unmarshal the string and pass the result back.<p>
+ *
+ * On asking for String, it will respond with the String
+ * if it exists, or marshal the String and pass the result back.<p>
+ *
+ * the "options" available on several functions control the output of this particular call. When
+ * blank, they will default to the DataFactory defaults. When present, they override this
+ * particular call.
+ * The available options are "pretty" (for XML and JSON) and "fragment" (XML only concept), which drops
+ * the "<?xml ...?>" header so you can create larger XML documents from the output.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public interface Data<T> {
+ static enum TYPE {XML,JSON,JAXB,RAW,DEFAULT};
+ // can & with 0xFFFF;
+// public static final int XML = 0x1;
+// public static final int JSON = 0x2;
+// public static final int JAXB = 0x4;
+// public static final int RAW = 0x1000;
+
+ // can & with 0xF00000;
+ public static final int PRETTY = 0x100000;
+ public static final int FRAGMENT = 0x200000;
+
+ /**
+ * Respond with the String if it exists, or marshal the String and pass the result back.
+ *
+ * However, use the Env the Data Object was created with.
+ *
+ * @return String
+ * @throws APIException
+ */
+ public String asString() throws APIException;
+
+ /**
+ * Respond with the Object of type {@literal <T>} if it exists, or unmarshal from String
+ * and pass the result back.<p>
+ *
+ * However, use the Env the Data Object was created with.
+ *
+ * @return T
+ * @throws APIException
+ */
+ public T asObject() throws APIException;
+
+ /**
+ * Set a particular option on an existing Out
+ *
+ * if int is negative, it should remove the option
+ * @param option
+ */
+ public Data<T> option(int option);
+
+ public Data<T> to(OutputStream os) throws APIException, IOException;
+ public Data<T> to(Writer writer) throws APIException, IOException;
+
+ public Data<T> load(T t) throws APIException;
+ public Data<T> load(String str) throws APIException;
+ public Data<T> load(InputStream is) throws APIException;
+ public Data<T> load(Reader rdr) throws APIException;
+
+ public Data<T> in(TYPE type);
+ public Data<T> out(TYPE type);
+ /**
+ * Return the Class Type supported by this DataObject
+ *
+ * @return {@literal Class<T>}
+ */
+ public Class<T> getTypeClass();
+
+ public void direct(InputStream input, OutputStream output) throws APIException, IOException;
+
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/DataFactory.java b/misc/env/src/main/java/org/onap/aaf/misc/env/DataFactory.java
new file mode 100644
index 0000000..4ce7eaf
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/DataFactory.java
@@ -0,0 +1,30 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+public interface DataFactory<T> {
+ public abstract Data<T> newData();
+ public abstract Data<T> newData(Env trans); // and Env or Trans object
+ public abstract Class<T> getTypeClass();
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Decryptor.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Decryptor.java
new file mode 100644
index 0000000..039cb2f
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Decryptor.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+public interface Decryptor {
+ public String decrypt(String tag);
+
+ public static final Decryptor NULL = new Decryptor() {
+ @Override
+ public String decrypt(String tag) {
+ return tag;
+ }
+ };
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Encryptor.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Encryptor.java
new file mode 100644
index 0000000..9e62113
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Encryptor.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+public interface Encryptor {
+ public String encrypt(String data);
+
+ public static final Encryptor NULL = new Encryptor() {
+ @Override
+ public String encrypt(String data) {
+ return data;
+ }
+ };
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Env.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Env.java
new file mode 100644
index 0000000..71f7922
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Env.java
@@ -0,0 +1,136 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+/**
+ * <H1>Env</H1>
+ * <i>Env</i> is the basic representation of what can be obtained from the
+ * Environment. Environments also need the ability to Log and Track Time, so
+ * to keep the interfaces clean, Env Interface inherits from Trans. This does NOT
+ * mean that all Environments are Transactions... It only means Environments need
+ * to Log and Track Times.
+ * .<p>
+ *
+ * Using this abstraction, Components can be built on a modular basis,
+ * and still have the essentials of functioning within the service mechanism.<p>
+ *
+ * Thus, for instance, an Module could be made to work in two separate
+ * service types, with substantial differences in choices of logging, or auditing,
+ * and still have reasonably deep insight, such as the exact time a
+ * remote service was invoked.<p>
+ *
+ * There is a bit of an assumption corresponding to the reality of the 2000s that
+ * XML plays a part in most service work.
+ *
+ * @author Jonathan
+ *
+ */
+public interface Env {
+ /**
+ * Very Severe Error may cause program to abort
+ */
+ public LogTarget fatal();
+
+ /**
+ * Severe Error, but program might continue running
+ */
+ public LogTarget error();
+
+ /**
+ * Required Audit statements
+ * @return
+ */
+ public LogTarget audit();
+
+ /**
+ * Initialization steps... Allows a Logger to separate startup info
+ * @return
+ */
+ public LogTarget init();
+
+ /**
+ * Potentially harmful situations
+ * @return
+ */
+ public LogTarget warn();
+
+ /**
+ * Course Grained highlights of program progress
+ * @return
+ */
+ public LogTarget info();
+
+ /**
+ * Fine-grained informational events useful for debugging
+ * @return
+ */
+ public LogTarget debug();
+
+ /**
+ * Finest grained Informational events... more detailed than Debug
+ * @return
+ */
+ public LogTarget trace();
+
+
+ /**
+ * Basic and Common Audit info...
+ *
+ * Note Apps can define, but should use Integers after 0x1F. They can combine with "&"
+ */
+ public static final int REMOTE = 0x01;
+ public static final int XML = 0x02;
+ public static final int JSON = 0x04;
+ public static final int SUB = 0x08;
+ public static final int CHECKPOINT = 0x10;
+ public static final int ALWAYS = 0x20; // Mark as a line to print, even in WARN+ mode
+
+
+
+ /**
+ * Start a Time Trail with differentiation by flag. This can be Defined By above flags or combined with
+ * app flag definitions
+ *
+ * @param string
+ * @param flag
+ * @return
+ */
+ public TimeTaken start(String name, int flag);
+
+ public String setProperty(String tag, String value);
+ public String getProperty(String tag);
+ public String getProperty(String tag, String deflt);
+
+ /**
+ * Passwords should be encrypted on the disk. Use this method to apply decryption before
+ * using. The Implementation should give ways to decrypt
+ *
+ * @param tag
+ * @return
+ */
+ public Decryptor decryptor();
+
+ public Encryptor encryptor();
+
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXB.java b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXB.java
new file mode 100644
index 0000000..27f423b
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXB.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+public interface EnvJAXB extends EnvStore<TransJAXB> {
+ /**
+ * Obtain a DataInterface from this Environment
+ *
+ * @param <T>
+ * @param classes
+ * @return
+ * @throws APIException
+ */
+ public <T> DataFactory<T> newDataFactory(Class<?>... classes) throws APIException;
+
+ /**
+ * Obtain a DataInterface from this Environment, with Validating Schema
+ *
+ * @param <T>
+ * @param classes
+ * @return
+ * @throws APIException
+ */
+ public <T> DataFactory<T> newDataFactory(Schema schema, Class<?>... classes) throws APIException;
+
+ public<T> DataFactory<T> newDataFactory(QName qName, Class<?> ... classes) throws APIException;
+
+ public<T> DataFactory<T> newDataFactory(Schema schema, QName qName, Class<?> ... classes) throws APIException;
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXBProps.java b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXBProps.java
new file mode 100644
index 0000000..1aba746
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvJAXBProps.java
@@ -0,0 +1,31 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+/**
+ * An interface to express both JAXB and Property elements of Env
+ * @author Jonathan
+ *
+ */
+public interface EnvJAXBProps extends EnvJAXB, EnvProps {
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/EnvProps.java b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvProps.java
new file mode 100644
index 0000000..2bfc027
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvProps.java
@@ -0,0 +1,80 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.util.Map;
+
+public interface EnvProps extends Env {
+ public interface EnvProperty {
+ public String getProperty(String input);
+ };
+
+ /**
+ * Obtain a Property (String) based on a Key. Implementor decides how
+ * that works, i.e. from a complex set of Configurations, or just
+ * "System" (Java standard)
+ *
+ * @param key
+ * @return APIException
+ */
+ public String getProperty(String key);
+
+ /**
+ * Obtain a Property (String) based on a Key. Implementor decides how
+ * that works, i.e. from a complex set of Configurations, or just
+ * "System" (Java standard)
+ *
+ * If Property Value is null, then default will be used.
+ * @param key
+ * @return APIException
+ */
+ public String getProperty(String tag, String defaultValue);
+
+ /**
+ * Set a Property (String) based on a Key accessible to all in Env. Implementor decides how
+ * that works, i.e. from a complex set of Configurations, or just
+ * "System" (Java standard)
+ *
+ * @param key
+ * @return APIException
+ */
+ public String setProperty(String key, String value);
+
+ /**
+ * Get the SubProperties based on key.
+ *
+ * use "false" to remove prefix, "true" to leave prefix in.
+ *
+ * @param key
+ * @return APIException
+ * Given a known property set (or in this case, properties starting with key),
+ * return map of all properties with appropriate key names
+ */
+ public Map<String, String> getSubProperties(String key, boolean includePrefix);
+
+ /**
+ * Get all of the properties in the Environment
+ * @return
+ */
+ public Map<String, String> getProperties();
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/EnvStore.java b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvStore.java
new file mode 100644
index 0000000..32dda01
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/EnvStore.java
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+public interface EnvStore<TRANS extends Trans> extends Env, Store, TransCreate<TRANS>{
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/IOObjectifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/IOObjectifier.java
new file mode 100644
index 0000000..d4e2868
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/IOObjectifier.java
@@ -0,0 +1,54 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+public interface IOObjectifier<T> extends Objectifier<T> {
+ /**
+ * Marshal to Object T from a Reader, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, Reader rdr) throws APIException;
+
+ /**
+ * Marshal to Object T from an InputStream, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, InputStream is) throws APIException;
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/IOStringifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/IOStringifier.java
new file mode 100644
index 0000000..1eab8db
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/IOStringifier.java
@@ -0,0 +1,74 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * Allow Extended IO interface usage without muddying up the Stringifier Interface
+ */
+public interface IOStringifier<T> extends Stringifier<T> {
+ /**
+ * Marshal from an Object T onto a Writer, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startTime(<string>, Env.XML)" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract void stringify(Env env, T input, Writer writer, boolean ... options) throws APIException;
+
+ /**
+ * Marshal from a String to an Object T, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract void stringify(Env env, T input, OutputStream os, boolean ... options) throws APIException;
+
+ /**
+ * Set Pretty XML, where possible
+ *
+ * @param pretty
+ * @throws APIException
+ */
+ public abstract IOStringifier<T> pretty(boolean pretty);
+
+ /**
+ * Set Generate Fragment
+ *
+ * @param fragment
+ * @throws APIException
+ */
+ public abstract IOStringifier<T> asFragment(boolean fragment);
+
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/LifeCycle.java b/misc/env/src/main/java/org/onap/aaf/misc/env/LifeCycle.java
new file mode 100644
index 0000000..3e14511
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/LifeCycle.java
@@ -0,0 +1,123 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ *
+ * Created on: Aug 19, 2009
+ * Created by: Jonathan
+ *
+ * (c) 2009 SBC Knowledge Ventures, L.P. All rights reserved.
+ *******************************************************************
+ * RESTRICTED - PROPRIETARY INFORMATION The Information contained
+ * herein is for use only by authorized employees of AT&T Services,
+ * Inc., and authorized Affiliates of AT&T Services, Inc., and is
+ * not for general distribution within or outside the respective
+ * companies.
+ *******************************************************************
+ */
+package org.onap.aaf.misc.env;
+
+import org.onap.aaf.misc.env.util.RefreshableThreadObject;
+
+
+/**
+ * @author Jonathan
+ *
+ */
+public interface LifeCycle {
+ /**
+ * The Service using LifeCycle Elements is required to call this method at
+ * the appropriate startup time. This is better for services than a simple
+ * static call, because the exact moment of starting can be determined
+ * programatically.
+ * <p>
+ *
+ * An excellent use is to establish security credentials with a backend
+ * after appropriate configurations have been read and available as part of
+ * the {@link Env} Object.
+ *
+ * @param env
+ * @throws APIException
+ */
+ public abstract void servicePrestart(Env env) throws APIException;
+
+ /**
+ * Many cases of implementations are not thread safe, and mechanisms must be
+ * derived to accomodate them by holding per Thread.
+ * <p>
+ *
+ * {@link ThreadLocal} is a valuable resource, but start up times within the
+ * thread, depending on what it is, can be substantial.
+ * <p>
+ *
+ * Use ThreadPrestart to do all that is possible before actually performing
+ * work, i.e. inside of a client transaction.
+ *
+ * @param env
+ * @throws APIException
+ */
+ public abstract void threadPrestart(Env env) throws APIException;
+
+ /**
+ * The Service will call this when (service-defined) configurations change.
+ * <p>
+ *
+ * This mechanism allows the Service to recognize events, such as file
+ * changes, and pass on the event to all LifeCycle implementors.
+ * <p>
+ *
+ * The code should take the opportunity to evaluate configuration and change
+ * as necessary.
+ * <p>
+ *
+ * <h2>IMPORTANT:</h2>
+ * The LifeCycle implementor cannot guarantee it will not be in the middle
+ * of a transaction, so it would behoove the implementor to construct
+ * content that does not affect anything until finished, then apply to an
+ * appropriate atomic action (i.e. setting an Object to a field), or even
+ * synchronizing.
+ *
+ * If you are using Java's "ThreadLocal", consider
+ * {@link RefreshableThreadObject}, because it implements LifeCycle, and
+ * responds to the refresh command.
+ *
+ * @param env
+ * @throws APIException
+ */
+ public abstract void refresh(Env env) throws APIException;
+
+ /**
+ * Parallel to threadPrestart, threadDestroy tells the implementor that the
+ * service is ending this particular thread, and to take this opportunity to
+ * close out any content specific to this thread that can be closed.
+ *
+ * @param env
+ * @throws APIException
+ */
+ public abstract void threadDestroy(Env env) throws APIException;
+
+ /**
+ * Parallel to servicePrestart, serviceDestroy tells the implementor that
+ * the service is ending, and to take this opportunity to close out any
+ * content under it's control that can or should be closed explicitly.
+ */
+ public abstract void serviceDestroy(Env env) throws APIException;
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/LogTarget.java b/misc/env/src/main/java/org/onap/aaf/misc/env/LogTarget.java
new file mode 100644
index 0000000..7ceaf95
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/LogTarget.java
@@ -0,0 +1,142 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.PrintStream;
+import java.util.Date;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+/**
+ * LogTarget is the interface with which to assign any kind of Logging Implementations.
+ *
+ * Implement for any Logging Library of your choice, and for any logging string Format desired.
+ *
+ * Included are several Static Implementations for various uses:
+ * NULL: Does nothing with Logging Messages
+ * SYSOUT: Writes messages in general form to System Out
+ * SYSERR: Writes messages in general form to System Err
+ *
+ * @author Jonathan
+ *
+ */
+public interface LogTarget {
+ public abstract void log(Object... msgs);
+ public abstract void log(Throwable e, Object ... msgs);
+ public abstract boolean isLoggable();
+ public abstract void printf(String fmt, Object ... vars);
+
+ // A Convenient LogTarget to insert when a NO-OP is desired.
+ public static final LogTarget NULL = new LogTarget() {
+ public void log(Object ... msgs) {
+ }
+
+ public void log(Throwable t, Object ... msgs) {
+ }
+
+ public boolean isLoggable() {
+ return false;
+ }
+
+ @Override
+ public void printf(String fmt, Object ... vars) {
+ }
+ };
+
+ // A Convenient LogTarget to write to the Console
+ public static final LogTarget SYSOUT = new LogTarget() {
+ public void log(Object ... msgs) {
+ PrintStream out = System.out;
+ out.print(org.onap.aaf.misc.env.util.Chrono.dateFmt.format(new Date()));
+ out.print(": ");
+ for(Object str : msgs) {
+ if(str!=null) {
+ out.print(str.toString());
+ out.print(' ');
+ } else {
+ out.print("null ");
+ }
+ }
+ out.println();
+ }
+
+ public void log(Throwable t, Object ... msgs) {
+ PrintStream out = System.out;
+ out.print(Chrono.dateFmt.format(new Date()));
+ out.print(": ");
+ for(Object str : msgs) {
+ out.print(str.toString());
+ out.print(' ');
+ }
+ out.println();
+ t.printStackTrace(out);
+ out.println();
+ }
+
+ public boolean isLoggable() {
+ return true;
+ }
+
+ @Override
+ public void printf(String fmt, Object ... vars) {
+ log(String.format(fmt,vars));
+ }
+ };
+
+ // A Convenient LogTarget to write to the Console
+ public static final LogTarget SYSERR = new LogTarget() {
+ public void log(Object ... msgs) {
+ PrintStream out = System.err;
+ out.print(Chrono.dateFmt.format(new Date()));
+ out.print(": ");
+ for(Object str : msgs) {
+ out.print(str.toString());
+ out.print(' ');
+ }
+ out.println();
+ out.flush();
+ }
+
+ public void log(Throwable t, Object ... msgs) {
+ PrintStream out = System.err;
+ out.print(Chrono.dateFmt.format(new Date()));
+ out.print(": ");
+ for(Object str : msgs) {
+ out.print(str.toString());
+ out.print(' ');
+ }
+ out.println();
+ t.printStackTrace(out);
+ }
+
+ public boolean isLoggable() {
+ return true;
+ }
+ @Override
+ public void printf(String fmt, Object ... vars) {
+ log(String.format(fmt,vars));
+ }
+
+ };
+
+
+};
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Objectifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Objectifier.java
new file mode 100644
index 0000000..09397de
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Objectifier.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ *
+ */
+package org.onap.aaf.misc.env;
+
+
+
+/**
+ * <h1>Objectifier</h1>
+ * <i>Objectifier</i> abstracts the unmarshaling of an Object from a String, and
+ * the creation of an uninitialized object.
+ */
+public interface Objectifier<T> extends LifeCycle {
+ /**
+ * Marshal to Object T from a String, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, String input) throws APIException;
+
+ /**
+ * Create a new object of type T. This is often more efficiently done with
+ * the underlying XML (or other) Library.
+ * @return T
+ * @throws APIException
+ */
+ public abstract T newInstance() throws APIException;
+
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Slot.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Slot.java
new file mode 100644
index 0000000..e202472
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Slot.java
@@ -0,0 +1,102 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ * Slot.java
+ *
+ * Created on: Dec 5, 2008
+ * Created by: Jonathan
+ *
+ * (c) 2008 SBC Knowledge Ventures, L.P. All rights reserved.
+ *******************************************************************
+ * RESTRICTED - PROPRIETARY INFORMATION The Information contained
+ * herein is for use only by authorized employees of AT&T Services,
+ * Inc., and authorized Affiliates of AT&T Services, Inc., and is
+ * not for general distribution within or outside the respective
+ * companies.
+ *******************************************************************
+ */
+package org.onap.aaf.misc.env;
+
+/**
+ * Slot's are used to store and retrieve data in the transaction's State object.
+ */
+public final class Slot {
+
+ /*
+ * The name of the Slot.
+ */
+ private final String key;
+
+ /*
+ * The index of the State's local map associated with this Slot.
+ */
+ final int slot;
+
+ /**
+ * Constructs a new Slot.
+ *
+ * @param index
+ * The index of State's local map this Slot is associated with.
+ * @param name
+ * The name of the Slot's key.
+ */
+ Slot(int index, String name) {
+ slot = index;
+ key = name;
+ }
+
+ /**
+ * Debug method only to print key=slot pairs.
+ */
+ public String toString() {
+ return key + '=' + slot;
+ }
+
+ /**
+ * Returns the name of this Slot's key.
+ *
+ * @return
+ * The name of this Slot's key.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Put an Object into the slot on the State
+ * @param state
+ * @param obj
+ */
+ public void put(Object[] state, Object obj) {
+ state[slot]=obj;
+ }
+
+ /**
+ * Get an Object from the slot on the State
+ * @param state
+ * @param obj
+ */
+ public Object get(Object[] state) {
+ return state[slot];
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/StaticSlot.java b/misc/env/src/main/java/org/onap/aaf/misc/env/StaticSlot.java
new file mode 100644
index 0000000..4a1033f
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/StaticSlot.java
@@ -0,0 +1,85 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ * Slot.java
+ *
+ * Created on: Dec 5, 2008
+ * Created by: Jonathan
+ *
+ * (c)2008 SBC Knowledge Ventures, L.P. All rights reserved.
+ *******************************************************************
+ * RESTRICTED - PROPRIETARY INFORMATION The Information contained
+ * herein is for use only by authorized employees of AT&T Services,
+ * Inc., and authorized Affiliates of AT&T Services, Inc., and is
+ * not for general distribution within or outside the respective
+ * companies.
+ *******************************************************************
+ */
+package org.onap.aaf.misc.env;
+
+/**
+ * StaticSlot's are used to store and retrieve data from the Organizer that does not change.
+ */
+public final class StaticSlot {
+
+ /*
+ * The name of the StaticSlot.
+ */
+ private final String key;
+
+ /*
+ * The index of the Organizer's static map associated with this StaticSlot.
+ */
+ final int slot;
+
+ /**
+ * Constructs a new StaticSlot.
+ *
+ * @param index
+ * The index of Organizer's static map this StaticSlot is associated with.
+ * @param name
+ * The name of the StaticSlot's key.
+ */
+ StaticSlot(int index, String name) {
+ slot = index;
+ key = name;
+ }
+
+ /**
+ * Debug method only to print key=slot pairs.
+ */
+ public String toString() {
+ return key + '=' + slot;
+ }
+
+ /**
+ * Returns the name of this StaticSlot's key.
+ *
+ * @return
+ * The name of this StaticSlot's key.
+ */
+ public String getKey() {
+ return key;
+ }
+
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Store.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Store.java
new file mode 100644
index 0000000..4e34dcd
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Store.java
@@ -0,0 +1,108 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.util.List;
+
+public interface Store {
+ /**
+ * Returns the Slot assigned to the supplied name.
+ *
+ * @param name
+ * The name of the Slot to acquire.
+ * @return
+ * The Slot associated with the supplied name.
+ */
+ public abstract Slot slot(String name);
+
+ /**
+ * Returns the existing Slot associated with the supplied name, or null if it doesn't exist.
+ *
+ * @param name
+ * The name of the Slot to get.
+ * @return
+ * The Slot assigned to the supplied name, or null if it doesn't exist.
+ *
+ */
+ public abstract Slot existingSlot(String name);
+
+ /**
+ * Returns the names used while creating Slots in a List
+ *
+ * @return
+ */
+ public abstract List<String> existingSlotNames();
+
+ /**
+ * Returns the StaticSlot assigned to the supplied name.
+ *
+ * @param name
+ * The name of the StaticSlot to acquire.
+ * @return
+ * The StaticSlot associated with the supplied name.
+ */
+ public abstract StaticSlot staticSlot(String name);
+
+ /**
+ * Returns the names used while creating Static Slots in a List
+ *
+ * @return
+ */
+ public abstract List<String> existingStaticSlotNames();
+
+ /**
+ * Store the supplied value in the StaticSlot of the Organizer's static state.
+ *
+ * @param slot
+ * The StaticSlot used to store the object.
+ * @param value
+ * The object to store.
+ */
+ public abstract void put(StaticSlot slot, Object value);
+
+ /**
+ * Returns an Object from the Organizer's static state, or the Default if null
+ *
+ * @param slot
+ * The StaticSlot to retrieve the data from.
+ * @return
+ * The Object located in the supplied StaticSlot of the Organizer's static state.
+ */
+ public abstract<T> T get(StaticSlot slot, T dflt);
+
+ /**
+ * Returns an Object from the Organizer's static state
+ *
+ * @param slot
+ * The StaticSlot to retrieve the data from.
+ * @return
+ * The Object located in the supplied StaticSlot of the Organizer's static state.
+ */
+ public abstract<T> T get(StaticSlot slot);
+
+// /**
+// * Transfer (targeted) Args to Slots
+// *
+// * Transfer Strings with format "tag=value" into Static Slots
+// */
+// public abstract void transfer(String args[], String ... tagss);
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/StoreImpl.java b/misc/env/src/main/java/org/onap/aaf/misc/env/StoreImpl.java
new file mode 100644
index 0000000..90fb1f2
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/StoreImpl.java
@@ -0,0 +1,240 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.GenericArrayType;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.onap.aaf.misc.env.util.Split;
+
+import java.util.Properties;
+
+
+public class StoreImpl implements Store {
+ /*
+ * The re-adjustment factor for growing the Static State array.
+ */
+ private static final int growSize = 10;
+
+ /*
+ * The index reference for Slot assignment.
+ */
+ private int local;
+
+ /*
+ * The index reference for StaticSlot assignment.
+ */
+ private int stat;
+
+ /*
+ * The name/slot map for local (transaction specific) State.
+ */
+ private HashMap<String, Slot> localMap;
+
+ /*
+ * The name/slot map for Static State.
+ */
+ private HashMap<String, StaticSlot> staticMap;
+
+ private Object[] staticState;
+
+ public StoreImpl() {
+ staticState = new Object[growSize];
+ staticMap = new HashMap<String,StaticSlot>();
+ localMap = new HashMap<String,Slot>();
+ }
+
+ public StoreImpl(String tag) {
+ staticState = new Object[growSize];
+ staticMap = new HashMap<String,StaticSlot>();
+ localMap = new HashMap<String,Slot>();
+ }
+
+
+ public StoreImpl(String tag, String[] args) {
+ staticState = new Object[growSize];
+ staticMap = new HashMap<String,StaticSlot>();
+ localMap = new HashMap<String,Slot>();
+
+ if(tag!=null) {
+ String tequals = tag + '=';
+ for(String arg : args) {
+ if(arg.startsWith(tequals) && !arg.equals(tequals)) { // needs to have something after =
+ Properties props = new Properties();
+ for(String f : Split.split(File.pathSeparatorChar,arg.substring(tequals.length()))) {
+ moreProps(new File(f),props);
+ }
+ for(Entry<Object, Object> es : props.entrySet()) {
+ put(staticSlot(es.getKey().toString()),es.getValue());
+ }
+ }
+ }
+ }
+
+ // Make sure properties on command line override those in Props
+ propsFromArgs(tag,args);
+ }
+
+ public StoreImpl(String tag, Properties props) {
+ staticState = new Object[growSize];
+ staticMap = new HashMap<String,StaticSlot>();
+ localMap = new HashMap<String,Slot>();
+
+ if(tag!=null) {
+ String fname = props.getProperty(tag);
+ if(fname!=null) {
+ for(String f : Split.split(File.pathSeparatorChar,fname)) {
+ if(!moreProps(new File(f),props)) {
+ System.err.println("Unable to load Properties from " + f);
+ }
+ }
+ }
+ }
+
+ for(Entry<Object, Object> es : props.entrySet()) {
+ put(staticSlot(es.getKey().toString()),es.getValue());
+ }
+ }
+
+ public void propsFromArgs(String tag, String[] args) {
+ if(tag!=null) {
+ for(String arg : args) {
+ String sarg[] = Split.split('=',arg);
+ if(sarg.length==2) {
+ if(tag.equals(sarg[0])) {
+ for(String fname : Split.split(File.pathSeparatorChar,sarg[1])) {
+ moreProps(new File(fname),null /* no target */);
+ }
+ }
+ put(staticSlot(sarg[0]),sarg[1]);
+ }
+ }
+ }
+ }
+
+ private boolean moreProps(File f, Properties target) {
+ if(f.exists()) {
+ Properties props = new Properties();
+ try {
+ FileInputStream fis = new FileInputStream(f);
+ try {
+ props.load(fis);
+ if(target!=null) {
+ target.load(fis);
+ }
+ } finally {
+ fis.close();
+ }
+ } catch(IOException e) {
+ System.err.println(e);
+ }
+ for(Entry<Object, Object> es : props.entrySet()) {
+ put(staticSlot(es.getKey().toString()),es.getValue());
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public Object[] newTransState() {
+ return new Object[local];
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#slot(java.lang.String)
+ */
+ public synchronized Slot slot(String name) {
+ name = name == null ? "" : name.trim();
+ Slot slot = localMap.get(name);
+ if (slot == null) {
+ slot = new Slot(local++, name);
+ localMap.put(name, slot);
+ }
+ return slot;
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#existingSlot(java.lang.String)
+ */
+ public Slot existingSlot(String name) {
+ return localMap.get(name);
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#existingSlotNames()
+ */
+ public List<String> existingSlotNames() {
+ return new ArrayList<String>(localMap.keySet());
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#staticSlot(java.lang.String)
+ */
+ public synchronized StaticSlot staticSlot(String name) {
+ name = name == null ? "" : name.trim();
+ StaticSlot slot = staticMap.get(name);
+ if (slot == null) {
+ if (stat%growSize == 0) {
+ Object[] temp = staticState;
+ staticState = new Object[temp.length+growSize];
+ System.arraycopy(temp, 0, staticState, 0, temp.length);
+ }
+ slot = new StaticSlot(stat++, name);
+ staticMap.put(name, slot);
+ }
+ return slot;
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#put(com.att.env.StaticSlot, java.lang.Object)
+ */
+ public void put(StaticSlot slot, Object value) {
+ staticState[slot.slot] = value;
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.env.Store#get(com.att.env.StaticSlot T defaultObject)
+ */
+ @SuppressWarnings("unchecked")
+ public<T> T get(StaticSlot sslot,T dflt) {
+ T t = (T)staticState[sslot.slot];
+ return t==null?dflt:t;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T get(StaticSlot sslot) {
+ return (T)staticState[sslot.slot];
+ }
+
+ public List<String> existingStaticSlotNames() {
+ return new ArrayList<String>(staticMap.keySet());
+ }
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Stringifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Stringifier.java
new file mode 100644
index 0000000..3d29366
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Stringifier.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+
+/**
+ * <h1>Stringifier</h1>
+ * <i>Stringifier</i> abstracts the marshaling of a String to an Object
+ */
+public interface Stringifier<T> extends LifeCycle {
+
+ /**
+ * Marshal from a String to an Object T, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract String stringify(Env env, T input, boolean ... options) throws APIException;
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java b/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java
new file mode 100644
index 0000000..053d4d6
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java
@@ -0,0 +1,116 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+/**
+ * <h1>TimeTaken</h1>
+ * This simple interface allows for many different kinds of
+ * Audit Logs to be accomplished, by assuming that the creation
+ * of this object indicates "start", and the calling of "done"
+ * ends.
+ *
+ * The implementor of this class can easily be stored in efficient
+ * mechanisms to minimize impact of Auditing on performance.
+ *
+ * @author Jonathan
+ *
+ */
+public abstract class TimeTaken {
+ public final long start;
+ protected long end, size;
+ public final int flag;
+ public final String name;
+
+ /**
+ * The name is as it will appear when written to output (abstract method)
+ *
+ * The flag is an integer which can be System type (XML, REMOTE, etc), or End User defined for reporting purposes
+ *
+ * @param name
+ * @param flag
+ */
+ public TimeTaken(String name, int flag) {
+ start = System.nanoTime();
+ this.flag = flag;
+ this.name = name;
+ size = -1;
+ }
+
+
+ /**
+ * Call this when process is done to state ending time.<p>
+ *
+ * It is <i>exceedingly prudent</i> to wrap the process called with a try-finally:<p>
+ *
+ * <pre>
+ * TimeTaken tt = env.startSubTime();
+ * try {
+ * process.me(); // code to be timed.
+ * } finally {
+ * tt.done();
+ * }
+ * </pre>
+ */
+ public void done() {
+ end = System.nanoTime();
+ }
+
+
+ /**
+ * For sizable contents, set the size. Implementations can simply write a no-op if they don't wish to
+ * store the size.
+ *
+ * @param size
+ */
+ public void size(long theSize) {
+ size = theSize;
+ }
+
+ /**
+ * Give readonly access to End, which isn't final
+ * @return
+ */
+ public long end() {
+ return end;
+ }
+
+ /**
+ * Time is taken in NanoSeconds. This method converts to decimals of Milliseconds
+ * @return
+ */
+ public float millis() {
+ return (end-start)/1000000f;
+ }
+ /**
+ * Write self to a String Builder (for making Audits)
+ * @param sb
+ */
+ public abstract void output(StringBuilder sb);
+
+ /**
+ * For Debugging
+ */
+ public String toString() {
+ return name + ' ' + millis() + "ms " + (size>0?Long.toString(size):"");
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/Trans.java b/misc/env/src/main/java/org/onap/aaf/misc/env/Trans.java
new file mode 100644
index 0000000..ced64e8
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/Trans.java
@@ -0,0 +1,74 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+
+
+
+/**
+ * A Trans is like an Env, however, it's purpose it to track the Transient
+ * Data associated with Transactions, or other short term elements.
+ *
+ * Any Object implementing Trans should expect to go in an out of scope quickly
+ *
+ * Implementations should also overload the concepts of "Start", etc and build up
+ * and Audit Log, so it can implement "metric" below
+ *
+ * All Transactions (i.e. a call to a service) will need these items.
+ *
+ * @author Jonathan
+ *
+ */
+public interface Trans extends Env {
+ /**
+ * Add a completed entry in the Audit Trail for tracking purposes.
+ *
+ * @param text
+ */
+ public void checkpoint(String text);
+
+ /**
+ * Add a completed entry in the Audit Trail for tracking purposes, and combine flag with "CHECKPOINT"
+ *
+ * @param text
+ */
+ public void checkpoint(String text, int additionalFlag);
+
+ /**
+ * Output an Audit Trail onto the StringBuilder
+ *
+ * Load metrics into an array of floats from passed in Flags
+ *
+ * @param flag
+ * @param sb
+ * @return
+ */
+ public Metric auditTrail(LogTarget lt, int indent, StringBuilder sb, int ... flag);
+
+ public Metric auditTrail(int indent, StringBuilder sb, int ... flag);
+
+ public class Metric {
+ public float[] buckets;
+ public float total;
+ public int entries;
+ }
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/TransCreate.java b/misc/env/src/main/java/org/onap/aaf/misc/env/TransCreate.java
new file mode 100644
index 0000000..7c16613
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/TransCreate.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+public interface TransCreate<TRANS> {
+ public TRANS newTrans();
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/TransJAXB.java b/misc/env/src/main/java/org/onap/aaf/misc/env/TransJAXB.java
new file mode 100644
index 0000000..dfc12b6
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/TransJAXB.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+public interface TransJAXB extends Trans, TransStore {
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/TransStore.java b/misc/env/src/main/java/org/onap/aaf/misc/env/TransStore.java
new file mode 100644
index 0000000..6b50313
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/TransStore.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env;
+
+public interface TransStore extends Trans {
+ /**
+ * Returns the Slot assigned to the supplied name.
+ *
+ * @param name
+ * The name of the Slot to acquire.
+ * @return
+ * The Slot associated with the supplied name.
+ */
+ public abstract Slot slot(String name);
+
+ /**
+ * Put data into the right slot
+ */
+ public void put(Slot slot, Object value);
+
+ /**
+ * Get data from the right slot
+ *
+ * This will do a cast to the expected type derived from Default
+ */
+ public<T> T get(Slot slot, T deflt);
+
+ /**
+ * Returns an Object from the Organizer's static state, or the Default if null
+ *
+ * @param slot
+ * The StaticSlot to retrieve the data from.
+ * @return
+ * The Object located in the supplied StaticSlot of the Organizer's static state.
+ */
+ public abstract<T> T get(StaticSlot slot, T dflt);
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java
new file mode 100644
index 0000000..a04b63e
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java
@@ -0,0 +1,214 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.StoreImpl;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.TransStore;
+
+public abstract class AbsTrans<ENV extends Env> implements TransStore {
+ private static final float[] EMPTYF = new float[0];
+ private static final Object[] EMPTYO = new Object[0];
+
+ protected ENV delegate;
+ protected List<TimeTaken> trail = new ArrayList<TimeTaken>(30);
+ private Object[] state;
+
+
+ public AbsTrans(ENV delegate) {
+ this.delegate = delegate;
+ state = delegate instanceof StoreImpl?((StoreImpl) delegate).newTransState():EMPTYO;
+ }
+
+ // @Override
+ public LogTarget fatal() {
+ return delegate.fatal();
+ }
+
+// @Override
+ public LogTarget error() {
+ return delegate.error();
+ }
+
+// @Override
+ public LogTarget audit() {
+ return delegate.audit();
+ }
+
+// @Override
+ public LogTarget init() {
+ return delegate.init();
+ }
+
+// @Override
+ public LogTarget warn() {
+ return delegate.warn();
+ }
+
+// @Override
+ public LogTarget info() {
+ return delegate.info();
+ }
+
+// @Override
+ public LogTarget debug() {
+ return delegate.debug();
+ }
+
+// @Override
+ public LogTarget trace() {
+ return delegate.trace();
+ }
+
+ /**
+ * Let the final Trans Implementation choose the exact kind of TimeTaken to use
+ * @param name
+ * @param flag
+ * @return
+ */
+ protected abstract TimeTaken newTimeTaken(String name, int flag);
+
+// @Override
+ public final TimeTaken start(String name, int flag) {
+ TimeTaken tt = newTimeTaken(name,flag);
+ trail.add(tt);
+ return tt;
+ }
+
+// @Override
+ public final void checkpoint(String name) {
+ TimeTaken tt = newTimeTaken(name,CHECKPOINT);
+ tt.done();
+ trail.add(tt);
+ }
+
+ public final void checkpoint(String name, int additionalFlag) {
+ TimeTaken tt = newTimeTaken(name,CHECKPOINT|additionalFlag);
+ trail.add(tt);
+ tt.done();
+ }
+
+ @Override
+ public Metric auditTrail(int indent, StringBuilder sb, int ... flags) {
+ return auditTrail(info(),indent,sb,flags);
+ }
+
+ @Override
+ public Metric auditTrail(LogTarget lt, int indent, StringBuilder sb, int ... flags) {
+ Metric metric = new Metric();
+ int last = (metric.entries = trail.size()) -1;
+ metric.buckets = flags.length==0?EMPTYF:new float[flags.length];
+ if(last>=0) {
+ TimeTaken first = trail.get(0);
+ // If first entry is sub, then it's actually the last "end" as well
+ // otherwise, check end
+ //long end = (first.flag&SUB)==SUB?first.end():trail.get(last).end();
+ long end = trail.get(last).end();
+ metric.total = (end - first.start) / 1000000f;
+ }
+
+ if(sb==null) {
+ for(TimeTaken tt : trail) {
+ float ms = tt.millis();
+ for(int i=0;i<flags.length;++i) {
+ if(tt.flag == flags[i]) metric.buckets[i]+=ms;
+ }
+ }
+ } else if(!lt.isLoggable()) {
+ boolean first = true;
+ for(TimeTaken tt : trail) {
+ float ms = tt.millis();
+ for(int i=0;i<flags.length;++i) {
+ if(tt.flag == flags[i]) metric.buckets[i]+=ms;
+ }
+ if((tt.flag&ALWAYS)==ALWAYS) {
+ if(first) first = false;
+ else sb.append('/');
+ sb.append(tt.name);
+ }
+ }
+ } else {
+ Stack<Long> stack = new Stack<Long>();
+ for(TimeTaken tt : trail) {
+ // Create Indentation based on SUB
+ while(!stack.isEmpty() && tt.end()>stack.peek()) {
+ --indent;
+ stack.pop();
+ }
+ for(int i=0;i<indent;++i) {
+ sb.append(" ");
+ }
+ tt.output(sb);
+ sb.append('\n');
+ if((tt.flag&SUB)==SUB) {
+ stack.push(tt.end());
+ ++indent;
+ }
+
+ // Add time values to Metric
+ float ms = tt.millis();
+ for(int i=0;i<flags.length;++i) {
+ if(tt.flag == flags[i]) metric.buckets[i]+=ms;
+ }
+ }
+ }
+ return metric;
+ }
+
+ /**
+ * Put data into the Trans State at the right slot
+ */
+// @Override
+ public void put(Slot slot, Object value) {
+ slot.put(state, value);
+ }
+
+ /**
+ * Get data from the Trans State from the right slot
+ *
+ * This will do a cast to the expected type derived from Default
+ */
+// @Override
+ @SuppressWarnings("unchecked")
+ public<T> T get(Slot slot, T deflt) {
+ Object o;
+ try {
+ o = slot.get(state);
+ } catch(ArrayIndexOutOfBoundsException e) {
+ // Env State Size has changed because of dynamic Object creation... Rare event, but needs to be covered
+ Object[] temp = ((StoreImpl) delegate).newTransState();
+ System.arraycopy(state, 0, temp, 0, state.length);
+ state = temp;
+ o=null;
+ }
+ return o==null?deflt:(T)o;
+ }
+
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTransJAXB.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTransJAXB.java
new file mode 100644
index 0000000..5c4a80b
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTransJAXB.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.DataFactory;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.TransJAXB;
+
+public abstract class AbsTransJAXB extends AbsTrans<EnvJAXB> implements TransJAXB {
+ public AbsTransJAXB(EnvJAXB env) {
+ super(env);
+ }
+
+// @Override
+ public <T> DataFactory<T> newDataFactory(Class<?>... classes) throws APIException {
+ return delegate.newDataFactory(classes);
+ }
+
+// @Override
+ public <T> DataFactory<T> newDataFactory(Schema schema, Class<?>... classes) throws APIException {
+ return delegate.newDataFactory(schema, classes);
+ }
+
+// @Override
+ public <T> DataFactory<T> newDataFactory(QName qName, Class<?>... classes) throws APIException {
+ return delegate.newDataFactory(qName, classes);
+ }
+
+// @Override
+ public <T> DataFactory<T> newDataFactory(Schema schema, QName qName, Class<?>... classes) throws APIException {
+ return delegate.newDataFactory(schema, qName, classes);
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicEnv.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicEnv.java
new file mode 100644
index 0000000..65fe9d8
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicEnv.java
@@ -0,0 +1,352 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import java.applet.Applet;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.DataFactory;
+import org.onap.aaf.misc.env.Decryptor;
+import org.onap.aaf.misc.env.Encryptor;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.StaticSlot;
+import org.onap.aaf.misc.env.StoreImpl;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.TransCreate;
+import org.onap.aaf.misc.env.TransJAXB;
+import org.onap.aaf.misc.env.jaxb.JAXBDF;
+import org.onap.aaf.misc.env.util.Split;
+
+/**
+ * An essential Implementation of Env, which will fully function, without any sort
+ * of configuration.
+ *
+ * Use as a basis for Group level Env, just overriding where needed.
+ * @author Jonathan
+ *
+ */
+public class BasicEnv extends StoreImpl implements EnvJAXB, TransCreate<TransJAXB>{
+ protected LogTarget fatal=LogTarget.SYSERR;
+ protected LogTarget error=LogTarget.SYSERR;
+ protected LogTarget audit=LogTarget.SYSOUT;
+ protected LogTarget init=LogTarget.SYSOUT;
+ protected LogTarget warn=LogTarget.SYSERR;
+ protected LogTarget info=LogTarget.SYSOUT;
+ protected LogTarget debug=LogTarget.NULL;
+ protected LogTarget trace=LogTarget.NULL;
+// protected Map<String, String> props;
+
+// private boolean sysprops;
+
+ public BasicEnv(String ... args) {
+ super(null,args);
+ }
+
+ public BasicEnv(String tag, String[] args) {
+ super(tag, args);
+ }
+
+
+ /**
+ * Suitable for use in Applets... obtain all the values
+ * listed for the variable String arg "tags"
+ */
+ public BasicEnv(Applet applet, String ... tags) {
+ super(null, tags);
+// props = new HashMap<String, String>();
+// String value;
+// for(int i=0;i<tags.length;++i) {
+// value = applet.getParameter(tags[i]);
+// if(value!=null) {
+// props.put(tags[i], value);
+// }
+// }
+ }
+
+ public BasicEnv(Properties props) {
+ super(null, props);
+ }
+
+ public BasicEnv(String tag, Properties props) {
+ super(tag, props);
+ }
+
+
+
+ // @Override
+ public LogTarget fatal() {
+ return fatal;
+ }
+
+ // @Override
+ public LogTarget error() {
+ return error;
+ }
+
+
+ // @Override
+ public LogTarget audit() {
+ return audit;
+ }
+
+ // @Override
+ public LogTarget init() {
+ return init;
+ }
+
+ // @Override
+ public LogTarget warn() {
+ return warn;
+ }
+
+ // @Override
+ public LogTarget info() {
+ return info;
+ }
+
+ // @Override
+ public LogTarget debug() {
+ return debug;
+ }
+
+ public void debug(LogTarget lt) {
+ debug = lt;
+ }
+
+ // @Override
+ public LogTarget trace() {
+ return trace;
+ }
+
+ // @Override
+ public TimeTaken start(String name, int flag) {
+ return new TimeTaken(name, flag) {
+ /**
+ * Format to be printed when called upon
+ */
+ // @Override
+ public void output(StringBuilder sb) {
+
+ switch(flag) {
+ case Env.XML: sb.append("XML "); break;
+ case Env.JSON: sb.append("JSON "); break;
+ case Env.REMOTE: sb.append("REMOTE "); break;
+ }
+ sb.append(name);
+ if(flag != Env.CHECKPOINT) {
+ sb.append(' ');
+ sb.append((end-start)/1000000f);
+ sb.append("ms");
+ if(size>=0) {
+ sb.append(" size: ");
+ sb.append(Long.toString(size));
+ }
+ }
+ }
+ };
+ }
+
+ // @Override
+ public String getProperty(String key) {
+ return get(staticSlot(key),null);
+ }
+
+ public Properties getProperties(String ... filter) {
+ Properties props = new Properties();
+ boolean yes;
+ for(String key : existingStaticSlotNames()) {
+ if(filter.length>0) {
+ yes = false;
+ for(String f : filter) {
+ if(key.startsWith(f)) {
+ yes = true;
+ break;
+ }
+ }
+ } else {
+ yes = true;
+ }
+ if(yes) {
+ String value = getProperty(key);
+ if(value!=null) {
+ props.put(key, value);
+ }
+ }
+ }
+ return props;
+ }
+
+ // @Override
+ public String getProperty(String key, String defaultValue) {
+ return get(staticSlot(key),defaultValue);
+ }
+
+ // @Override
+ public String setProperty(String key, String value) {
+ put(staticSlot(key),value==null?null:value.trim());
+ return value;
+ }
+
+ protected Decryptor decryptor = Decryptor.NULL;
+ protected Encryptor encryptor = Encryptor.NULL;
+
+
+ public Decryptor decryptor() {
+ return decryptor;
+ }
+
+ public void set(Decryptor newDecryptor) {
+ decryptor = newDecryptor;
+ }
+
+ public Encryptor encryptor() {
+ return encryptor;
+ }
+
+ public void set(Encryptor newEncryptor) {
+ encryptor = newEncryptor;
+ }
+
+
+// @SuppressWarnings("unchecked")
+ // @Override
+ public <T> DataFactory<T> newDataFactory(Class<?>... classes) throws APIException {
+// if(String.class.isAssignableFrom(classes[0]))
+// return (DataFactory<T>) new StringDF(this);
+ return new JAXBDF<T>(this,classes);
+ }
+
+// @SuppressWarnings("unchecked")
+ // @Override
+ public <T> DataFactory<T> newDataFactory(Schema schema, Class<?>... classes) throws APIException {
+// if(String.class.isAssignableFrom(classes[0]))
+// return (DataFactory<T>) new StringDF(this);
+ return new JAXBDF<T>(this, schema, classes);
+ }
+
+// @SuppressWarnings("unchecked")
+ // @Override
+ public<T> DataFactory<T> newDataFactory(QName qName, Class<?> ... classes) throws APIException {
+// if(String.class.isAssignableFrom(classes[0]))
+// return (DataFactory<T>) new StringDF(this);
+ return new JAXBDF<T>(this, qName, classes);
+ }
+
+ // @Override
+ public<T> DataFactory<T> newDataFactory(Schema schema, QName qName, Class<?> ... classes) throws APIException {
+ return new JAXBDF<T>(this, schema, qName, classes);
+ }
+
+ // @Override
+ public BasicTrans newTrans() {
+ return new BasicTrans(this);
+ }
+
+ public void loadFromSystemPropsStartsWith(String ... str) {
+ for(String name : System.getProperties().stringPropertyNames()) {
+ for(String s : str) {
+ if(name.startsWith(s)) {
+ setProperty(name, System.getProperty(name));
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ public void loadToSystemPropsStartsWith(String ... str) {
+ String value;
+ for(String name : existingStaticSlotNames()) {
+ for(String s : str) {
+ if(name.startsWith(s)) {
+ if((value = getProperty(name))!=null)
+ System.setProperty(name,value);
+ }
+ }
+ }
+ }
+
+ public void loadPropFiles(String tag, ClassLoader classloader) throws IOException {
+ String propfiles = getProperty(tag);
+ if(propfiles!=null) {
+ for(String pf : Split.splitTrim(File.pathSeparatorChar, propfiles)) {
+ InputStream is = classloader==null?null:classloader.getResourceAsStream(pf);
+ if(is==null) {
+ File f = new File(pf);
+ if(f.exists()) {
+ is = new FileInputStream(f);
+ }
+ }
+ if(is!=null) {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ try {
+ String line;
+ while((line=br.readLine())!=null) {
+ line = line.trim();
+ if(!line.startsWith("#")) {
+ String[] tv = Split.splitTrim('=', line);
+ if(tv.length==2) {
+ setProperty(tv[0],tv[1]);
+ }
+ }
+ }
+ } finally {
+ try {
+ br.close();
+ } catch (IOException e) {
+ error().log(e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a StaticSlot, and load it from existing Properties
+ *
+ * @param name
+ * @param propName
+ * @return
+ */
+ public synchronized StaticSlot staticSlot(String name, final String propName) {
+ StaticSlot ss = staticSlot(name);
+ put(ss,getProperty(propName));
+ return ss;
+ }
+
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicTrans.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicTrans.java
new file mode 100644
index 0000000..eb33ff5
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicTrans.java
@@ -0,0 +1,81 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import org.onap.aaf.misc.env.Decryptor;
+import org.onap.aaf.misc.env.Encryptor;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.StaticSlot;
+import org.onap.aaf.misc.env.TimeTaken;
+
+
+public class BasicTrans extends AbsTransJAXB {
+
+ public BasicTrans(EnvJAXB env) {
+ super(env);
+ }
+
+ @Override
+ protected TimeTaken newTimeTaken(String name, int flag) {
+ /**
+ * Note: could have created a different format for Time Taken, but using BasicEnv's instead
+ */
+ return delegate.start(name, flag);
+ }
+
+ public Slot slot(String name) {
+ return delegate.slot(name);
+ }
+
+ public <T> T get(StaticSlot slot) {
+ return delegate.get(slot);
+ }
+
+ public <T> T get(StaticSlot slot, T dflt) {
+ return delegate.get(slot,dflt);
+ }
+
+ public String setProperty(String tag, String value) {
+ delegate.setProperty(tag, value);
+ return value;
+ }
+
+ public String getProperty(String tag) {
+ return delegate.getProperty(tag);
+ }
+
+ public String getProperty(String tag, String deflt) {
+ return delegate.getProperty(tag, deflt);
+ }
+
+ @Override
+ public Decryptor decryptor() {
+ return delegate.decryptor();
+ }
+
+ @Override
+ public Encryptor encryptor() {
+ return delegate.encryptor();
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/EnvFactory.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/EnvFactory.java
new file mode 100644
index 0000000..a882c74
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/EnvFactory.java
@@ -0,0 +1,68 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.TransCreate;
+import org.onap.aaf.misc.env.TransJAXB;
+
+/**
+ * EnvFactory
+ *
+ * @author Jonathan
+ *
+ */
+public class EnvFactory {
+
+ public static final String SCHEMA_DIR = "env-schema_dir";
+ public static final String DEFAULT_SCHEMA_DIR = "src/main/xsd";
+ static BasicEnv singleton;
+
+ static {
+ singleton = new BasicEnv();
+ }
+ public static BasicEnv singleton() {
+ return singleton;
+ }
+
+ public static void setSingleton(BasicEnv be) {
+ singleton = be;
+ }
+
+ public static TransJAXB newTrans() {
+ return new BasicTrans(singleton);
+ }
+
+ public static TransJAXB newTrans(EnvJAXB env) {
+ return new BasicTrans(env);
+ }
+
+ public static TransCreate<TransJAXB> transCreator() {
+ return new TransCreate<TransJAXB>() {
+ // @Override
+ public BasicTrans newTrans() {
+ return singleton.newTrans();
+ }
+ };
+ }
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/JavaUtilLogTarget.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/JavaUtilLogTarget.java
new file mode 100644
index 0000000..84a78bf
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/JavaUtilLogTarget.java
@@ -0,0 +1,90 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.onap.aaf.misc.env.LogTarget;
+
+/**
+ * This LogTarget Implementation is included mostly because the JavaUtil based logging is included in the
+ * JDK. This makes the default implementation independent of any external Jars.
+ *
+ * Log4j is often considered more Enterprise capable. See Log4JLogTarget for that implementation
+ *
+ * @author Jonathan
+ *
+ */
+public class JavaUtilLogTarget implements LogTarget {
+ private Level level;
+ private Logger log;
+
+ public JavaUtilLogTarget(Logger logger, Level theLevel) {
+ log = logger;
+ level = theLevel;
+ }
+
+ public boolean isLoggable() {
+ return log.isLoggable(level);
+ }
+
+ public void log(Object ... msgs) {
+ if(log.isLoggable(level)) {
+ StringBuilder sb = new StringBuilder();
+ String msg;
+ for(int i=0;i<msgs.length;++i) {
+ msg = msgs[i].toString();
+ if(msg!=null && msg.length()>0) {
+ int sbl = sb.length();
+ if(sbl>0) {
+ char last = sb.charAt(sbl-1);
+ if(" (.".indexOf(last)<0 && "().".indexOf(msg.charAt(0))<0)sb.append(' ');
+ }
+ sb.append(msg);
+ }
+ }
+ log.log(level, sb.toString());
+ }
+ }
+
+ public void log(Throwable e, Object ... msgs) {
+ String str = e.getLocalizedMessage();
+ if(str==null) {
+ str = e.getMessage();
+ }
+ if(str==null) {
+ str = e.getClass().getName();
+ }
+ log.log(level,str,msgs);
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.inno.env.LogTarget#printf(java.lang.String, java.lang.String[])
+ */
+ @Override
+ public void printf(String fmt, Object ... vars) {
+ if(log.isLoggable(level)) {
+ log.log(level,String.format(fmt,vars));
+ }
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/Log4JLogTarget.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/Log4JLogTarget.java
new file mode 100644
index 0000000..44da65e
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/Log4JLogTarget.java
@@ -0,0 +1,109 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.impl;
+
+import java.io.PrintWriter;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+
+/**
+ * Many services have chosen to use Log4J for their lower level Logging Implementation. This LogTarget will allow
+ * any of the messages sent to be set to the appropriate Log4J level.
+ *
+ * @author Jonathan
+ *
+ */
+public class Log4JLogTarget implements LogTarget {
+ private Level level;
+ private Logger log;
+
+ public Log4JLogTarget(String loggerName, Level level) throws APIException {
+ this.level = level;
+ if (loggerName != null && loggerName.length() > 0) {
+ log = Logger.getLogger(loggerName);
+ } else {
+ log = Logger.getRootLogger();
+ }
+ }
+
+ // @Override
+ public boolean isLoggable() {
+ return log.isEnabledFor(level);
+ }
+
+ // @Override
+ public void log(Object... msgs) {
+ log(null, msgs);
+ }
+
+ // @Override
+ public void log(Throwable e, Object... msgs) {
+ if (log.isEnabledFor(level)) {
+ StringBuilder sb = new StringBuilder();
+
+ String msg;
+ if (e != null) {
+ e.printStackTrace(new PrintWriter(new StringBuilderWriter(sb)));
+ }
+ for (int i = 0; i < msgs.length; ++i) {
+ if(msgs[i]!=null) {
+ msg = msgs[i].toString();
+ if (msg != null && msg.length() > 0) {
+ int sbl = sb.length();
+ if (sbl > 0) {
+ char last = sb.charAt(sbl - 1);
+ if (" (.".indexOf(last) < 0
+ && "().".indexOf(msg.charAt(0)) < 0)
+ sb.append(' ');
+ }
+ sb.append(msg);
+ }
+ }
+ }
+ log.log(level, sb.toString());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.inno.env.LogTarget#printf(java.lang.String, java.lang.String[])
+ */
+ @Override
+ public void printf(String fmt, Object ... vars) {
+ if(log.isEnabledFor(level)) {
+ log.log(level,String.format(fmt,vars));
+ }
+ }
+
+ public static void setLog4JEnv(String loggerName, BasicEnv env) throws APIException {
+ env.fatal = new Log4JLogTarget(loggerName,Level.FATAL);
+ env.error = new Log4JLogTarget(loggerName,Level.ERROR);
+ env.warn = env.audit = env.init = new Log4JLogTarget(loggerName,Level.WARN);
+ env.info = new Log4JLogTarget(loggerName,Level.INFO);
+ env.debug = new Log4JLogTarget(loggerName,Level.DEBUG);
+ env.trace = new Log4JLogTarget(loggerName,Level.TRACE);
+ }
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/NullLifeCycle.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/NullLifeCycle.java
new file mode 100644
index 0000000..5cda17f
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/NullLifeCycle.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ *
+ */
+package org.onap.aaf.misc.env.impl;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LifeCycle;
+
+
+
+/**
+ * <h1>NullLifeCycle</h1>
+ *
+ * This is a convenience class for those Objects which should
+ * implement LifeCycle, but don't have anything to do in any of the
+ * LifeCycle methods defined. Extending
+ * NullLifeCycle reduces the required methods for the class by 5.
+ * Any one or two of them can be overloaded.<p>
+ *
+ * If more are overloaded, it is
+ * recommended just to implement LifeCycle.
+ * <p>
+ *
+ * This only works, though, if the Object doesn't need to extend something
+ * else, due to Java's Single Extension policy. In other cases, just
+ * implement LifeCycle, and leave them empty.
+ *
+ * @author Jonathan
+ *
+ */
+public class NullLifeCycle implements LifeCycle {
+ public void servicePrestart(Env env) throws APIException {}
+ public void threadPrestart(Env env) throws APIException {}
+ public void refresh(Env env) throws APIException {}
+ public void threadDestroy(Env env) throws APIException {}
+ public void serviceDestroy(Env env) throws APIException {}
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBDF.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBDF.java
new file mode 100644
index 0000000..74fcc83
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBDF.java
@@ -0,0 +1,309 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.BaseDataFactory;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.old.IOObjectifier;
+import org.onap.aaf.misc.env.old.IOStringifier;
+import org.onap.aaf.misc.env.old.OldDataFactory;
+
+public class JAXBDF<T> extends BaseDataFactory implements OldDataFactory<T>,IOObjectifier<T>, IOStringifier<T> {
+ // Package on purpose
+ EnvJAXB primaryEnv;
+ JAXBumar jumar;
+ JAXBmar jmar;
+
+ public JAXBDF(EnvJAXB env, Class<?> ... classes) throws APIException {
+ try {
+ primaryEnv = env;
+ jumar = new JAXBumar(classes);
+ jmar = new JAXBmar(classes) ;
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public JAXBDF(EnvJAXB env, Schema schema, Class<?> ... classes) throws APIException {
+ try {
+ primaryEnv = env;
+ jumar = new JAXBumar(schema, classes);
+ jmar = new JAXBmar(classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public JAXBDF(EnvJAXB env, QName qname, Class<?> ... classes) throws APIException {
+ try {
+ primaryEnv = env;
+ jumar = new JAXBumar(classes);
+ jmar = new JAXBmar(qname, classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public JAXBDF(EnvJAXB env, Schema schema, QName qname, Class<?> ... classes) throws APIException {
+ try {
+ primaryEnv = env;
+ jumar = new JAXBumar(schema, classes);
+ jmar = new JAXBmar(qname, classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public T newInstance() throws APIException {
+ try {
+ return jumar.newInstance();
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public IOStringifier<T> pretty(boolean pretty) {
+ jmar.pretty(pretty);
+ return this;
+ }
+
+ // @Override
+ public IOStringifier<T> asFragment(boolean fragment) {
+ jmar.asFragment(fragment);
+ return this;
+ }
+
+ // @Override
+ public void servicePrestart(Env env) throws APIException {
+ }
+
+ // @Override
+ public void threadPrestart(Env env) throws APIException {
+ }
+
+ // @Override
+ public void refresh(Env env) throws APIException {
+ }
+
+ // @Override
+ public void threadDestroy(Env env) throws APIException {
+ }
+
+ // @Override
+ public void serviceDestroy(Env env) throws APIException {
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Data<T> newData() {
+ return new JAXBData<T>(primaryEnv, this, new JAXBStringifier<T>(jmar), new JAXBObjectifier<T>(jumar),"",(Class<T>)jmar.getMarshalClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Data<T> newData(Env env) {
+ return new JAXBData<T>(env, this,new JAXBStringifier<T>(jmar), new JAXBObjectifier<T>(jumar),"",(Class<T>)jmar.getMarshalClass());
+ }
+
+ // @Override
+ public Data<T> newData(T type) {
+ return new JAXBData<T>(primaryEnv, this, new JAXBStringifier<T>(jmar), new JAXBObjectifier<T>(jumar), type);
+ }
+
+ // @Override
+ public Data<T> newDataFromStream(Env env, InputStream input) throws APIException {
+ //TODO Write an unvalidated String using STAX checking for end of Doc?
+ // perhaps key evaluation as well.
+ try {
+ T t = jumar.unmarshal(env.debug(), input);
+ return new JAXBData<T>(primaryEnv, this, new JAXBStringifier<T>(jmar), new JAXBObjectifier<T>(jumar),t);
+ } catch(JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Data<T> newDataFromString(String string) {
+ return new JAXBData<T>(primaryEnv, this,new JAXBStringifier<T>(jmar), new JAXBObjectifier<T>(jumar), string,(Class<T>)jmar.getMarshalClass());
+ }
+
+ /////////// Old DataFactory Interface
+ // @Override
+ public String stringify(T type) throws APIException {
+ try {
+ StringWriter sw = new StringWriter();
+ jmar.marshal(primaryEnv.debug(), type, sw);
+ return sw.toString();
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public void stringify(T type, Writer writer) throws APIException {
+ try {
+ jmar.marshal(primaryEnv.debug(), type, writer);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public void stringify(T type, OutputStream os) throws APIException {
+ try {
+ jmar.marshal(primaryEnv.debug(), type, os);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ /////////// New DataFactory Interface
+ // @Override
+ public String stringify(Env env, T input, boolean ... options) throws APIException {
+ try {
+ StringWriter sw = new StringWriter();
+ TimeTaken tt = env.start("JAXB Stringify", Env.XML);
+ try {
+ jmar.marshal(env.debug(), input, sw, options);
+ } finally {
+ tt.done();
+ }
+ String str = sw.toString();
+ tt.size(str.getBytes().length);
+ return str;
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public void stringify(Env env, T input, Writer writer, boolean ... options) throws APIException {
+ TimeTaken tt = env.start("JAXB Stringify", Env.XML);
+ try {
+ jmar.marshal(env.debug(), input, writer, options);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public void stringify(Env env, T input, OutputStream os, boolean ... options) throws APIException {
+ TimeTaken tt = env.start("JAXB Stringify", Env.XML);
+ try {
+ jmar.marshal(env.debug(), input, os, options);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public T objectify(Env env, Reader rdr) throws APIException {
+ TimeTaken tt = env.start("JAXB Objectify", Env.XML);
+ try {
+ return jumar.unmarshal(env.debug(), rdr);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public T objectify(Reader rdr) throws APIException {
+ try {
+ return jumar.unmarshal(primaryEnv.debug(), rdr);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public T objectify(Env env, InputStream is) throws APIException {
+ TimeTaken tt = env.start("JAXB Objectify", Env.XML);
+ try {
+ return jumar.unmarshal(env.debug(), is);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public T objectify(InputStream is) throws APIException {
+ try {
+ return jumar.unmarshal(primaryEnv.debug(), is);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // @Override
+ public T objectify(Env env, String input) throws APIException {
+ TimeTaken tt = env.start("JAXB Objectify", Env.XML);
+ tt.size(input.getBytes().length);
+ try {
+ return jumar.unmarshal(env.debug(), input);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public T objectify(String text) throws APIException {
+ try {
+ return jumar.unmarshal(primaryEnv.debug(), text);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Class<T> getTypeClass() {
+ return (Class<T>)jmar.getMarshalClass();
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBData.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBData.java
new file mode 100644
index 0000000..e1c54c6
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBData.java
@@ -0,0 +1,321 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.xml.bind.JAXBException;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.old.IOStringifier;
+import org.onap.aaf.misc.env.old.Objectifier;
+import org.onap.aaf.misc.env.old.Stringifier;
+/**
+ * <H1>Data</H1>
+ * <i>Data</i> facilitates lazy marshaling of data with a pre-determined
+ * marshaling mechanism.<p>
+ *
+ * It stores either Object (defined by Generic {@literal <T>}) or String.<p>
+ *
+ * On asking for Object of type {@literal <T>}, it will respond with the object
+ * if it exists, or unmarshal the string and pass the result back.<p>
+ *
+ * On asking for String, it will respond with the String
+ * if it exists, or marshal the String and pass the result back.<p>
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public final class JAXBData<T> implements Data<T>{
+ private Stringifier<T> stringifier;
+ private Objectifier<T> objectifier;
+ private String dataAsString;
+ private T dataAsObject;
+ private Class<T> tclass;
+ private JAXBDF<T> df;
+ private Env creatingEnv;
+ private boolean options[] = new boolean[] {false, false};
+
+ /**
+ * Construct a Data Object with an appropriate Stringifier, Objectifier and Class to support
+ *
+ * @param env
+ * @param strfr
+ * @param objfr
+ * @param text
+ * @param typeClass
+ */
+ JAXBData(Env env, JAXBDF<T> df, Stringifier<T> strfr, Objectifier<T> objfr, String text, Class<T> typeClass) {
+ dataAsString = text;
+ dataAsObject = null;
+ stringifier = strfr;
+ objectifier = objfr;
+ tclass = typeClass;
+ creatingEnv = env;
+ this.df = df;
+ }
+
+
+ /**
+ * Construct a Data Object with an appropriate Stringifier, Objectifier and Object (which will
+ * yield it's class)
+ *
+ * @param env
+ * @param strfr
+ * @param objfr
+ * @param object
+ */
+ @SuppressWarnings("unchecked")
+ JAXBData(Env env, JAXBDF<T> df, Stringifier<T> strfr, Objectifier<T> objfr, T object) {
+ dataAsString = null;
+ dataAsObject = object;
+ stringifier = strfr;
+ objectifier = objfr;
+ tclass = (Class<T>) object.getClass();
+ creatingEnv = env;
+ this.df = df;
+ }
+
+ /**
+ * Respond with the String if it exists, or marshal the String and pass the result back.<p>
+ *
+ * Explicitly use a specific Env for logging purposes
+ *
+ * @param env
+ * @return String
+ * @throws APIException
+ */
+ public String asString(EnvJAXB env) throws APIException {
+ if(dataAsString!=null) {
+ return dataAsString;
+ } else {
+ return dataAsString = stringifier.stringify(env, dataAsObject);
+ }
+ }
+
+ /**
+ * Respond with the String if it exists, or marshal the String and pass the result back.
+ *
+ * However, use the Env the Data Object was created with.
+ *
+ * @return String
+ * @throws APIException
+ */
+ // @Override
+ public String asString() throws APIException {
+ if(dataAsString!=null) {
+ return dataAsString;
+ } else {
+ return dataAsString = stringifier.stringify(creatingEnv, dataAsObject,options);
+ }
+ }
+
+ public Data<T> to(OutputStream os) throws APIException, IOException {
+ if(dataAsString!=null) {
+ os.write(dataAsString.getBytes());
+ } else if (stringifier instanceof IOStringifier){
+ ((IOStringifier<T>)stringifier).stringify(creatingEnv, dataAsObject, os, options);
+ } else {
+ dataAsString = stringifier.stringify(creatingEnv, dataAsObject, options);
+ os.write(dataAsString.getBytes());
+ }
+ return this;
+ }
+
+
+ // @Override
+ public JAXBData<T> to(Writer writer) throws APIException, IOException {
+ if(dataAsString!=null) {
+ writer.write(dataAsString);
+ } else if (stringifier instanceof IOStringifier){
+ ((IOStringifier<T>)stringifier).stringify(creatingEnv, dataAsObject, writer, options);
+ } else {
+ dataAsString = stringifier.stringify(creatingEnv, dataAsObject, options);
+ writer.write(dataAsString);
+ }
+ return this;
+ }
+
+
+ public InputStream getInputStream() throws APIException {
+ if(dataAsString==null) {
+ dataAsString = stringifier.stringify(creatingEnv,dataAsObject,options);
+ }
+ return new ByteArrayInputStream(dataAsString.getBytes());
+ }
+
+ /**
+ * Respond with the Object of type {@literal <T>} if it exists, or unmarshal from String
+ * and pass the result back.<p>
+ *
+ * Explicitly use a specific Env for logging purposes
+ *
+ * @param env
+ * @return T
+ * @throws APIException
+ */
+
+ public T asObject(EnvJAXB env) throws APIException {
+ if(dataAsObject !=null) {
+ return dataAsObject;
+ } else {
+ // Some Java compilers need two statements here
+ dataAsObject = objectifier.objectify(env, dataAsString);
+ return dataAsObject;
+ }
+ }
+
+ /**
+ * Respond with the Object of type {@literal <T>} if it exists, or unmarshal from String
+ * and pass the result back.<p>
+ *
+ * However, use the Env the Data Object was created with.
+ *
+ * @return T
+ * @throws APIException
+ */
+ // @Override
+ public T asObject() throws APIException {
+ if(dataAsObject !=null) {
+ return dataAsObject;
+ } else {
+ // Some Java compilers need two statements here
+ dataAsObject = objectifier.objectify(creatingEnv, dataAsString);
+ return dataAsObject;
+ }
+ }
+
+
+ /**
+ * Return the Class Type supported by this DataObject
+ *
+ * @return {@literal Class<T>}
+ */
+ // @Override
+ public Class<T> getTypeClass() {
+ return tclass;
+ }
+
+
+ /**
+ * For Debugging Convenience, we marshal to String if possible.
+ *
+ * Behavior is essentially the same as asString(), except asString() throws
+ * an APIException. <p>
+ * Since toString() must not throw exceptions, the function just catches and prints an
+ * error, which is probably not the behavior desired.<p>
+ *
+ * Therefore, use "asString()" where possible in actual Transactional code.
+ *
+ * @see java.lang.Object#toString()
+ */
+ // @Override
+ public String toString() {
+ if(dataAsString!=null) {
+ return dataAsString;
+ } else {
+ try {
+ return dataAsString = stringifier.stringify(creatingEnv, dataAsObject);
+ } catch (APIException e) {
+ return "ERROR - Can't Stringify from Object " + e.getLocalizedMessage();
+ }
+ }
+ }
+
+ public Data<T> load(T t) throws APIException {
+ dataAsObject = t;
+ dataAsString = null;
+ return this;
+ }
+
+
+ public Data<T> load(String str) throws APIException {
+ dataAsObject = null;
+ dataAsString = str;
+ return this;
+ }
+
+
+ public Data<T> load(InputStream is) throws APIException {
+ try {
+ dataAsObject = df.jumar.unmarshal(creatingEnv.debug(),is);
+ dataAsString = null;
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ return this;
+ }
+
+
+ public Data<T> load(Reader rdr) throws APIException {
+ try {
+ dataAsObject = df.jumar.unmarshal(creatingEnv.debug(),rdr);
+ dataAsString = null;
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ return this;
+ }
+
+
+ // @Override
+ public void direct(InputStream input, OutputStream output) throws APIException, IOException {
+ byte b[] = new byte[128];
+ int count;
+ do {
+ count = input.read(b);
+ if(count>0)output.write(b, 0, count);
+ } while(count>=0);
+ }
+
+
+ // @Override
+ public Data<T> out(TYPE type) {
+ // it's going to be XML regardless...
+ return this;
+ }
+
+
+ // @Override
+ public Data<T> in(TYPE type) {
+ // Not Supported... will still be XML
+ return this;
+ }
+
+
+ // @Override
+ public Data<T> option(int option) {
+ options[0] = (option&Data.PRETTY)==Data.PRETTY;
+ options[1] = (option&Data.FRAGMENT)==Data.FRAGMENT;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBObjectifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBObjectifier.java
new file mode 100644
index 0000000..9679d84
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBObjectifier.java
@@ -0,0 +1,135 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.old.IOObjectifier;
+
+/**
+ * Allow Extended IO interface usage without muddying up the Stringifier Interface
+ */
+public class JAXBObjectifier<T> implements IOObjectifier<T> {
+ private JAXBumar jumar;
+
+ public JAXBObjectifier(Schema schema, Class<?>... classes) throws APIException {
+ try {
+ jumar = new JAXBumar(schema, classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public JAXBObjectifier(Class<?>... classes) throws APIException {
+ try {
+ jumar = new JAXBumar(classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // package on purpose
+ JAXBObjectifier(JAXBumar jumar) {
+ this.jumar = jumar;
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public T objectify(Env env, String input) throws APIException {
+ TimeTaken tt = env.start("JAXB Unmarshal", Env.XML);
+ try {
+ tt.size(input.length());
+ return (T)jumar.unmarshal(env.debug(), input);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public T objectify(Env env, Reader rdr) throws APIException {
+ //TODO create a Reader that Counts?
+ TimeTaken tt = env.start("JAXB Unmarshal", Env.XML);
+ try {
+ return (T)jumar.unmarshal(env.debug(), rdr);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public T objectify(Env env, InputStream is) throws APIException {
+ //TODO create a Reader that Counts?
+ TimeTaken tt = env.start("JAXB Unmarshal", Env.XML);
+ try {
+ return (T)jumar.unmarshal(env.debug(), is);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+ public void servicePrestart(Env env) throws APIException {
+ }
+
+ public void threadPrestart(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void refresh(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void threadDestroy(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void serviceDestroy(Env env) throws APIException {
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public T newInstance() throws APIException {
+ try {
+ return (T)jumar.newInstance();
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBStringifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBStringifier.java
new file mode 100644
index 0000000..5bed4fd
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBStringifier.java
@@ -0,0 +1,137 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.old.IOStringifier;
+
+public class JAXBStringifier<T> implements IOStringifier<T> {
+ private JAXBmar jmar;
+
+ public JAXBStringifier(Class<?>... classes) throws APIException {
+ try {
+ jmar = new JAXBmar(classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public JAXBStringifier(QName qname, Class<?>... classes)
+ throws APIException {
+ try {
+ jmar = new JAXBmar(qname, classes);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ // package on purpose
+ JAXBStringifier(JAXBmar jmar) {
+ this.jmar = jmar;
+ }
+
+ // // @Override
+ public void stringify(Env env, T input, Writer writer, boolean ... options)
+ throws APIException {
+ TimeTaken tt = env.start("JAXB Marshal", Env.XML);
+ try {
+ jmar.marshal(env.debug(), input, writer, options);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public void stringify(Env env, T input, OutputStream os, boolean ... options)
+ throws APIException {
+ // TODO create an OutputStream that Counts?
+ TimeTaken tt = env.start("JAXB Marshal", Env.XML);
+ try {
+ jmar.marshal(env.debug(), input, os, options);
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public String stringify(Env env, T input, boolean ... options) throws APIException {
+ TimeTaken tt = env.start("JAXB Marshal", Env.XML);
+ StringWriter sw = new StringWriter();
+ try {
+ jmar.marshal(env.debug(), input, sw, options);
+ String rv = sw.toString();
+ tt.size(rv.length());
+ return rv;
+ } catch (JAXBException e) {
+ tt.size(0);
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // // @Override
+ public void servicePrestart(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void threadPrestart(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void refresh(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void threadDestroy(Env env) throws APIException {
+ }
+
+ // // @Override
+ public void serviceDestroy(Env env) throws APIException {
+ }
+
+ // @Override
+ public JAXBStringifier<T> pretty(boolean pretty) {
+ jmar.pretty(pretty);
+ return this;
+ }
+
+ // @Override
+ public JAXBStringifier<T> asFragment(boolean fragment) {
+ jmar.asFragment(fragment);
+ return this;
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBmar.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBmar.java
new file mode 100644
index 0000000..f35ffb7
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBmar.java
@@ -0,0 +1,253 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ * JAXBumar.java
+ *
+ * Created on: Apr 10, 2009
+ * Created by: Jonathan
+ *
+ * Revamped to do away with ThreadLocal 5/27/2011, JG1555
+ *
+ * (c) 2009 SBC Knowledge Ventures, L.P. All rights reserved.
+ *******************************************************************
+ * RESTRICTED - PROPRIETARY INFORMATION The Information contained
+ * herein is for use only by authorized employees of AT&T Services,
+ * Inc., and authorized Affiliates of AT&T Services, Inc., and is
+ * not for general distribution within or outside the respective
+ * companies.
+ *******************************************************************
+ */
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.namespace.QName;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.util.Pool;
+import org.onap.aaf.misc.env.util.Pool.Pooled;
+
+/**
+ * JAXBmar classes are inexpensive for going in and out of scope
+ * and have been made thread safe via Pooling
+
+ * @author Jonathan
+ *
+ */
+public class JAXBmar {
+ // Need to store off possible JAXBContexts based on Class, which will be stored in Creator
+ private static Map<Class<?>[],Pool<PMarshaller>> pools = new HashMap<Class<?>[], Pool<PMarshaller>>();
+
+ // Handle Marshaller class setting of properties only when needed
+ private class PMarshaller {
+ private Marshaller m;
+ private boolean p;
+ private boolean f;
+
+ public PMarshaller(Marshaller marshaller) throws JAXBException {
+ m = marshaller;
+ m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, p = false);
+ m.setProperty(Marshaller.JAXB_FRAGMENT, f = false);
+ }
+
+ public Marshaller get(boolean pretty, boolean fragment) throws JAXBException {
+ if(pretty != p) {
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, p = pretty);
+ }
+ if(fragment != f) {
+ m.setProperty(Marshaller.JAXB_FRAGMENT, f = fragment);
+ }
+ return m;
+ }
+ }
+
+ private class Creator implements Pool.Creator<PMarshaller> {
+ private JAXBContext jc;
+ private String name;
+ public Creator(Class<?>[] classes) throws JAXBException {
+ jc = JAXBContext.newInstance(classes);
+ name = "JAXBmar: " + classes[0].getName();
+ }
+
+ // @Override
+ public PMarshaller create() throws APIException {
+ try {
+ return new PMarshaller(jc.createMarshaller());
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ // @Override
+ public void reuse(PMarshaller pm) {
+ // Nothing to do
+ }
+
+ // @Override
+ public void destroy(PMarshaller pm) {
+ // Nothing to do
+ }
+
+ // @Override
+ public boolean isValid(PMarshaller t) {
+ return true;
+ }
+ }
+
+ //TODO isn't UTF-8 a standard string somewhere for encoding?
+ private boolean fragment= false;
+ private boolean pretty=false;
+ private QName qname;
+
+ private Pool<PMarshaller> mpool; // specific Pool associated with constructed Classes
+ private Class<?> cls;
+
+ private Pool<PMarshaller> getPool(Class<?> ... classes) throws JAXBException {
+ Pool<PMarshaller> mp;
+ synchronized(pools) {
+ mp = pools.get(classes);
+ if(mp==null) {
+ pools.put(classes,mp = new Pool<PMarshaller>(new Creator(classes)));
+ }
+ }
+ return mp;
+ }
+
+ public JAXBmar(Class<?>... classes) throws JAXBException {
+ cls = classes[0];
+ mpool = getPool(classes);
+ qname = null;
+ }
+
+ public JAXBmar(QName theQname, Class<?>... classes) throws JAXBException {
+ cls = classes[0];
+ mpool = getPool(classes);
+ qname = theQname;
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O marshal(LogTarget lt,O o, Writer writer, boolean ... options) throws JAXBException, APIException {
+ boolean pretty, fragment;
+ pretty = options.length>0?options[0]:this.pretty;
+ fragment = options.length>1?options[1]:this.fragment;
+ Pooled<PMarshaller> m = mpool.get(lt);
+ try {
+ if(qname==null) {
+ m.content.get(pretty,fragment).marshal(o, writer);
+ } else {
+ m.content.get(pretty,fragment).marshal(
+ new JAXBElement<O>(qname, (Class<O>)cls, o ),
+ writer);
+ }
+ return o;
+ } finally {
+ m.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O marshal(LogTarget lt, O o, OutputStream os, boolean ... options) throws JAXBException, APIException {
+ boolean pretty, fragment;
+ pretty = options.length>0?options[0]:this.pretty;
+ fragment = options.length>1?options[1]:this.fragment;
+ Pooled<PMarshaller> m = mpool.get(lt);
+ try {
+ if(qname==null) {
+ m.content.get(pretty,fragment).marshal(o, os);
+ } else {
+ m.content.get(pretty,fragment).marshal(
+ new JAXBElement<O>(qname, (Class<O>)cls, o ),os);
+ }
+ return o;
+ } finally {
+ m.done();
+ }
+ }
+
+ public<O> O marshal(LogTarget lt, O o, Writer writer, Class<O> clss) throws JAXBException, APIException {
+ Pooled<PMarshaller> m = mpool.get(lt);
+ try {
+ if(qname==null) {
+ m.content.get(pretty,fragment).marshal(o, writer);
+ } else {
+ m.content.get(pretty,fragment).marshal(
+ new JAXBElement<O>(qname, clss, o),writer);
+ }
+ return o;
+ } finally {
+ m.done();
+ }
+
+ }
+
+ public<O> O marshal(LogTarget lt, O o, OutputStream os, Class<O> clss) throws JAXBException, APIException {
+ Pooled<PMarshaller> m = mpool.get(lt);
+ try {
+ if(qname==null) {
+ m.content.get(pretty,fragment).marshal(o, os);
+ } else {
+ m.content.get(pretty,fragment).marshal(
+ new JAXBElement<O>(qname, clss, o ),os);
+ }
+ return o;
+ } finally {
+ m.done();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public Class<?> getMarshalClass() {
+ return cls;
+ }
+
+ public<O> String stringify(LogTarget lt, O o) throws JAXBException, APIException {
+ StringWriter sw = new StringWriter();
+ marshal(lt,o,sw);
+ return sw.toString();
+ }
+
+ public JAXBmar pretty(boolean pretty) {
+ this.pretty = pretty;
+ return this;
+ }
+
+ public JAXBmar asFragment(boolean fragment) {
+ this.fragment = fragment;
+ return this;
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBumar.java b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBumar.java
new file mode 100644
index 0000000..7e60bce
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/jaxb/JAXBumar.java
@@ -0,0 +1,243 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ * JAXBumar.java
+ *
+ * Created on: Apr 10, 2009
+ * Created by: Jonathan
+ *
+ * Revamped to do away with ThreadLocal 5/27/2011, JG1555
+ *
+ * (c) 2009 SBC Knowledge Ventures, L.P. All rights reserved.
+ *******************************************************************
+ * RESTRICTED - PROPRIETARY INFORMATION The Information contained
+ * herein is for use only by authorized employees of AT&T Services,
+ * Inc., and authorized Affiliates of AT&T Services, Inc., and is
+ * not for general distribution within or outside the respective
+ * companies.
+ *******************************************************************
+ */
+package org.onap.aaf.misc.env.jaxb;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.util.Pool;
+import org.onap.aaf.misc.env.util.Pool.Pooled;
+import org.w3c.dom.Node;
+
+/**
+ * JAXBumar classes are inexpensive for going in and out of scope
+ * and have been made thread safe via Pooling
+ *
+ * @author Jonathan
+ *
+ */
+public class JAXBumar {
+ // Need to store off possible JAXBContexts based on Class, which will be stored in Creator
+ private static Map<Class<?>[],Pool<SUnmarshaller>> pools = new HashMap<Class<?>[], Pool<SUnmarshaller>>();
+
+ private Class<?> cls;
+ private Schema schema;
+ private Pool<SUnmarshaller> mpool;;
+
+ // Handle Marshaller class setting of properties only when needed
+ private class SUnmarshaller {
+ private Unmarshaller u;
+ private Schema s;
+
+ public SUnmarshaller(Unmarshaller unmarshaller) throws JAXBException {
+ u = unmarshaller;
+ s = null;
+ }
+
+ public Unmarshaller get(Schema schema) throws JAXBException {
+ if(s != schema) {
+ u.setSchema(s = schema);
+ }
+ return u;
+ }
+ }
+
+ private class Creator implements Pool.Creator<SUnmarshaller> {
+ private JAXBContext jc;
+ private String name;
+
+ public Creator(Class<?>[] classes) throws JAXBException {
+ jc = JAXBContext.newInstance(classes);
+ name = "JAXBumar: " + classes[0].getName();
+ }
+
+ // @Override
+ public SUnmarshaller create() throws APIException {
+ try {
+ return new SUnmarshaller(jc.createUnmarshaller());
+ } catch (JAXBException e) {
+ throw new APIException(e);
+ }
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ // @Override
+ public void destroy(SUnmarshaller sui) {
+ // Nothing to do
+ }
+
+ // @Override
+ public boolean isValid(SUnmarshaller t) {
+ return true;
+ }
+
+ // @Override
+ public void reuse(SUnmarshaller t) {
+ // Nothing to do here
+ }
+
+ }
+
+ private Pool<SUnmarshaller> getPool(Class<?> ... classes) throws JAXBException {
+ Pool<SUnmarshaller> mp;
+ synchronized(pools) {
+ mp = pools.get(classes);
+ if(mp==null) {
+ pools.put(classes,mp = new Pool<SUnmarshaller>(new Creator(classes)));
+ }
+ }
+ return mp;
+ }
+
+ public JAXBumar(Class<?> ... classes) throws JAXBException {
+ cls = classes[0];
+ mpool = getPool(classes);
+ schema = null;
+ }
+
+ /**
+ * Constructs a new JAXBumar with schema validation enabled.
+ *
+ * @param schema
+ * @param theClass
+ * @throws JAXBException
+ */
+ public JAXBumar(Schema schema, Class<?> ... classes) throws JAXBException {
+ cls = classes[0];
+ mpool = getPool(classes);
+ this.schema = schema;
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, Node node) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return s.content.get(schema).unmarshal(node,(Class<O>)cls).getValue();
+ } finally {
+ s.done();
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, String xml) throws JAXBException, APIException {
+ if(xml==null) throw new JAXBException("Null Input for String unmarshal");
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(
+ new StreamSource(new StringReader(xml))
+ ,(Class<O>)cls).getValue();
+ } finally {
+ s.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, File xmlFile) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(xmlFile);
+ } finally {
+ s.done();
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env,InputStream is) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(is);
+ } finally {
+ s.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, Reader rdr) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(rdr);
+ } finally {
+ s.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, XMLStreamReader xsr) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(xsr,(Class<O>)cls).getValue();
+ } finally {
+ s.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O unmarshal(LogTarget env, XMLEventReader xer) throws JAXBException, APIException {
+ Pooled<SUnmarshaller> s = mpool.get(env);
+ try {
+ return (O)s.content.get(schema).unmarshal(xer,(Class<O>)cls).getValue();
+ } finally {
+ s.done();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public<O> O newInstance() throws InstantiationException, IllegalAccessException{
+ return ((Class<O>)cls).newInstance();
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOObjectifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOObjectifier.java
new file mode 100644
index 0000000..65c5a36
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOObjectifier.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.old;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+
+public interface IOObjectifier<T> extends Objectifier<T> {
+ /**
+ * Marshal to Object T from a Reader, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, Reader rdr) throws APIException;
+
+ /**
+ * Marshal to Object T from an InputStream, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, InputStream is) throws APIException;
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOStringifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOStringifier.java
new file mode 100644
index 0000000..c5f57b9
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/old/IOStringifier.java
@@ -0,0 +1,77 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.old;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+
+/**
+ * Allow Extended IO interface usage without muddying up the Stringifier Interface
+ */
+public interface IOStringifier<T> extends Stringifier<T> {
+ /**
+ * Marshal from an Object T onto a Writer, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startTime(<string>, Env.XML)" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract void stringify(Env env, T input, Writer writer, boolean ... options) throws APIException;
+
+ /**
+ * Marshal from a String to an Object T, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract void stringify(Env env, T input, OutputStream os, boolean ... options) throws APIException;
+
+ /**
+ * Set Pretty XML, where possible
+ *
+ * @param pretty
+ * @throws APIException
+ */
+ public abstract IOStringifier<T> pretty(boolean pretty);
+
+ /**
+ * Set Generate Fragment
+ *
+ * @param fragment
+ * @throws APIException
+ */
+ public abstract IOStringifier<T> asFragment(boolean fragment);
+
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/old/Objectifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/old/Objectifier.java
new file mode 100644
index 0000000..6ec72ba
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/old/Objectifier.java
@@ -0,0 +1,60 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/**
+ *
+ */
+package org.onap.aaf.misc.env.old;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LifeCycle;
+
+
+/**
+ * <h1>Objectifier</h1>
+ * <i>Objectifier</i> abstracts the unmarshaling of an Object from a String, and
+ * the creation of an uninitialized object.
+ */
+public interface Objectifier<T> extends LifeCycle {
+ /**
+ * Marshal to Object T from a String, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return T
+ * @throws APIException
+ */
+ public abstract T objectify(Env env, String input) throws APIException;
+
+ /**
+ * Create a new object of type T. This is often more efficiently done with
+ * the underlying XML (or other) Library.
+ * @return T
+ * @throws APIException
+ */
+ public abstract T newInstance() throws APIException;
+
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/old/OldDataFactory.java b/misc/env/src/main/java/org/onap/aaf/misc/env/old/OldDataFactory.java
new file mode 100644
index 0000000..a434261
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/old/OldDataFactory.java
@@ -0,0 +1,47 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.old;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.DataFactory;
+import org.onap.aaf.misc.env.Env;
+
+public interface OldDataFactory<T> extends DataFactory<T> {
+ public abstract String stringify(T type) throws APIException;
+ public abstract void stringify(T type, OutputStream os) throws APIException;
+ public abstract void stringify(T type, Writer writer) throws APIException;
+ public abstract T objectify(InputStream is) throws APIException;
+ public abstract T objectify(Reader rdr) throws APIException;
+ public abstract T objectify(String text) throws APIException;
+ public abstract T newInstance() throws APIException;
+ public abstract Data<T> newData(T type);
+ public abstract Data<T> newDataFromStream(Env env, InputStream input) throws APIException;
+ public abstract Data<T> newDataFromString(String string);
+
+}
+
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/old/Stringifier.java b/misc/env/src/main/java/org/onap/aaf/misc/env/old/Stringifier.java
new file mode 100644
index 0000000..7dcdf34
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/old/Stringifier.java
@@ -0,0 +1,48 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.old;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LifeCycle;
+
+
+/**
+ * <h1>Stringifier</h1>
+ * <i>Stringifier</i> abstracts the marshaling of a String to an Object
+ */
+public interface Stringifier<T> extends LifeCycle {
+
+ /**
+ * Marshal from a String to an Object T, using contents from Env as necessary.<p>
+ *
+ * Implementations should use the {@link Env} to call "env.startXMLTime()" to mark
+ * XML time, since this is often a costly process.
+ *
+ * @param env
+ * @param input
+ * @return String
+ * @throws APIException
+ */
+ public abstract String stringify(Env env, T input, boolean ... options) throws APIException;
+
+}
\ No newline at end of file
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/Chrono.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Chrono.java
new file mode 100644
index 0000000..74fbef6
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Chrono.java
@@ -0,0 +1,310 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.security.SecureRandom;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public class Chrono {
+ private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+
+ public final static DateFormat dateFmt, dateOnlyFmt, niceDateFmt, utcFmt,iso8601Fmt;
+ // Give general access to XML DataType Factory, since it's pretty common
+ public static final DatatypeFactory xmlDatatypeFactory;
+
+ static {
+ try {
+ xmlDatatypeFactory = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ dateOnlyFmt = new SimpleDateFormat("yyyy-MM-dd");
+ niceDateFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm zzz");
+ dateFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ utcFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ iso8601Fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
+ utcFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+
+ public static class Formatter8601 extends Formatter {
+
+ @Override
+ public String format(LogRecord r) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(dateFmt.format(new Date(r.getMillis())));
+ sb.append(' ');
+ sb.append(r.getThreadID());
+ sb.append(' ');
+ sb.append(r.getLevel());
+ sb.append(": ");
+ sb.append(r.getMessage());
+ sb.append('\n');
+ return sb.toString();
+ }
+
+ }
+
+ /**
+ * timeStamp
+ *
+ * Convenience method to setup an XML dateTime (XMLGregorianCalendar) with "now"
+ * @return
+ */
+ public static XMLGregorianCalendar timeStamp() {
+ return xmlDatatypeFactory.newXMLGregorianCalendar(new GregorianCalendar());
+ }
+
+ /**
+ * timestamp
+ *
+ * Convenience method to setup an XML dateTime (XMLGregorianCalendar) with passed in Date
+ * @param date
+ * @return
+ */
+ public static XMLGregorianCalendar timeStamp(Date date) {
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(date);
+ return xmlDatatypeFactory.newXMLGregorianCalendar(gc);
+ }
+
+ public static XMLGregorianCalendar timeStamp(GregorianCalendar gc) {
+ return xmlDatatypeFactory.newXMLGregorianCalendar(gc);
+ }
+
+ public static String utcStamp() {
+ return utcFmt.format(new Date());
+ }
+
+ public static String utcStamp(Date date) {
+ if(date==null)return "";
+ return utcFmt.format(date);
+ }
+
+ public static String utcStamp(GregorianCalendar gc) {
+ if(gc==null)return "";
+ return utcFmt.format(gc.getTime());
+ }
+
+ public static String utcStamp(XMLGregorianCalendar xgc) {
+ if(xgc==null)return "";
+ return utcFmt.format(xgc.toGregorianCalendar().getTime());
+ }
+
+ public static String dateStamp() {
+ return dateFmt.format(new Date());
+ }
+
+ public static String dateStamp(GregorianCalendar gc) {
+ if(gc == null)return "";
+ return dateFmt.format(gc.getTime());
+ }
+
+ public static String dateStamp(Date date) {
+ if(date == null)return "";
+ return dateFmt.format(date);
+ }
+
+ public static String dateStamp(XMLGregorianCalendar xgc) {
+ if(xgc==null)return "";
+ return dateFmt.format(xgc.toGregorianCalendar().getTime());
+ }
+
+ /**
+ * JAXB compatible dataTime Stamp
+ *
+ * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.
+ *
+ * @return
+ */
+ public static String dateTime() {
+ return dateTime(new GregorianCalendar());
+ }
+
+ /**
+ * JAXB compatible dataTime Stamp
+ *
+ * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.
+ *
+ * @return
+ */
+ public static String dateTime(Date date) {
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(date);
+ return dateTime(gc);
+ }
+
+ /**
+ * JAXB compatible dataTime Stamp
+ *
+ * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.
+ *
+ * @return
+ */
+ public static String dateTime(GregorianCalendar gc) {
+ if(gc == null)return "";
+ TimeZone tz = gc.getTimeZone();
+ int tz1 = (tz.getRawOffset()+tz.getDSTSavings())/0x8CA0;
+ int tz1abs = Math.abs(tz1);
+ return String.format("%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d:%02d",
+ gc.get(GregorianCalendar.YEAR),
+ gc.get(GregorianCalendar.MONTH)+1,
+ gc.get(GregorianCalendar.DAY_OF_MONTH),
+ gc.get(GregorianCalendar.HOUR),
+ gc.get(GregorianCalendar.MINUTE),
+ gc.get(GregorianCalendar.SECOND),
+ gc.get(GregorianCalendar.MILLISECOND),
+ tz1==tz1abs?'+':'-',
+ tz1abs/100,
+ ((tz1abs-(tz1abs/100)*100)*6)/10 // Get the "10s", then convert to mins (without losing int place)
+ );
+ }
+
+ /**
+ * JAXB compatible dataTime Stamp
+ *
+ * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.
+ *
+ * @return
+ */
+ public static String dateTime(XMLGregorianCalendar xgc) {
+ return xgc==null?"":dateTime(xgc.toGregorianCalendar());
+ }
+
+ public static String dateOnlyStamp() {
+ return dateOnlyFmt.format(new Date());
+ }
+
+ public static String dateOnlyStamp(GregorianCalendar gc) {
+ return gc == null?"":dateOnlyFmt.format(gc.getTime());
+ }
+
+ public static String dateOnlyStamp(Date date) {
+ return date == null?"":dateOnlyFmt.format(date);
+ }
+
+ public static String dateOnlyStamp(XMLGregorianCalendar xgc) {
+ return xgc==null?"":dateOnlyFmt.format(xgc.toGregorianCalendar().getTime());
+ }
+
+ public static String niceDateStamp() {
+ return niceDateFmt.format(new Date());
+ }
+
+ public static String niceDateStamp(Date date) {
+ return date==null?"":niceDateFmt.format(date);
+ }
+
+ public static String niceDateStamp(GregorianCalendar gc) {
+ return gc==null?"":niceDateFmt.format(gc.getTime());
+ }
+
+ public static String niceDateStamp(XMLGregorianCalendar xgc) {
+ return xgc==null?"":niceDateFmt.format(xgc.toGregorianCalendar().getTime());
+ }
+
+
+ ////////////////////// HELPFUL Strings
+ public static final String BAD_DIR_CHARS_REGEX = "[/:\\;.]";
+ public static final String SPLIT_DIR_REGEX = "/";
+
+ public static long firstMomentOfDay(long utc) {
+ GregorianCalendar begin = new GregorianCalendar();
+ begin.setTimeInMillis(utc);
+ return firstMomentOfDay(begin).getTimeInMillis();
+ }
+
+ public static long lastMomentOfDay(long utc) {
+ GregorianCalendar end = new GregorianCalendar();
+ end.setTimeInMillis(utc);
+ return lastMomentOfDay(end).getTimeInMillis();
+ }
+
+ public static GregorianCalendar firstMomentOfDay(GregorianCalendar begin) {
+ if(begin==null)begin = new GregorianCalendar();
+ begin.set(GregorianCalendar.HOUR, 0);
+ begin.set(GregorianCalendar.AM_PM, GregorianCalendar.AM);
+ begin.set(GregorianCalendar.MINUTE, 0);
+ begin.set(GregorianCalendar.SECOND, 0);
+ begin.set(GregorianCalendar.MILLISECOND, 0);
+ return begin;
+ }
+
+ public static GregorianCalendar lastMomentOfDay(GregorianCalendar end) {
+ if(end==null)end = new GregorianCalendar();
+ end.set(GregorianCalendar.HOUR, 11);
+ end.set(GregorianCalendar.MINUTE, 59);
+ end.set(GregorianCalendar.SECOND, 59);
+ end.set(GregorianCalendar.MILLISECOND, 999);
+ end.set(GregorianCalendar.AM_PM, GregorianCalendar.PM);
+ return end;
+ }
+
+ // UUID needs to be converted from UUID Epoch
+ public static final Date uuidToDate(UUID id) {
+ return new Date((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000);
+ }
+
+ public static final long uuidToUnix(UUID id) {
+ return (id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000;
+ }
+
+ public static float millisFromNanos(long start, long end) {
+ return (end - start) / 1000000f;
+ }
+
+
+ private static long sequence = new SecureRandom().nextInt();
+ private static synchronized long sequence() {
+ return ++sequence;
+ }
+
+ public static final UUID dateToUUID(Date origTime) {
+ return dateToUUID(origTime.getTime());
+ }
+
+ public static final UUID dateToUUID(long origTime) {
+ /*
+ * From Cassandra : http://wiki.apache.org/cassandra/FAQ
+ Magic number obtained from #cassandra's thobbs, who
+ claims to have stolen it from a Python library.
+ */
+ long time = origTime * 10000 + NUM_100NS_INTERVALS_SINCE_UUID_EPOCH;
+ long timeLow = time & 0xffffffffL;
+ long timeMid = time & 0xffff00000000L;
+ long timeHi = time & 0xfff000000000000L;
+ long upperLong = (timeLow << 32) | (timeMid >> 16) | (1 << 12) | (timeHi >> 48) ;
+ return new java.util.UUID(upperLong, (0xC000000000000000L | sequence()));
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/DoubleOutputStream.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/DoubleOutputStream.java
new file mode 100644
index 0000000..0bce473
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/DoubleOutputStream.java
@@ -0,0 +1,97 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class DoubleOutputStream extends OutputStream {
+ private OutputStream[] oss;
+ private boolean[] close;
+
+ /**
+ * Create a Double Stream Writer
+ * Some Streams should not be closed by this object (i.e. System.out), therefore, mark them with booleans
+ */
+ public DoubleOutputStream(OutputStream a, boolean closeA, OutputStream b, boolean closeB) {
+ oss = new OutputStream[] {a,b};
+ close = new boolean[] {closeA,closeB};
+ }
+
+ /**
+ * Write a single character.
+ * @throws IOException
+ */
+ @Override
+ public void write(int c) throws IOException {
+ for(OutputStream os : oss) {
+ os.write(c);
+ }
+ }
+
+ /**
+ * Write a portion of an array of characters.
+ *
+ * @param bbuf Array of characters
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ * @throws IOException
+ */
+ @Override
+ public void write(byte bbuf[], int off, int len) throws IOException {
+ for(OutputStream os : oss) {
+ os.write(bbuf,off,len);
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ for(OutputStream os : oss) {
+ os.write(b);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.OutputStream#close()
+ */
+ @Override
+ public void close() throws IOException {
+ for(int i=0;i<oss.length;++i) {
+ if(close[i]) {
+ oss[i].close();
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.OutputStream#flush()
+ */
+ @Override
+ public void flush() throws IOException {
+ for(OutputStream os : oss) {
+ os.flush();
+ }
+ }
+
+
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/IPValidator.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/IPValidator.java
new file mode 100644
index 0000000..d6ac850
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/IPValidator.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.util.regex.Pattern;
+
+public class IPValidator {
+ private static final Pattern ipv4_p = Pattern.compile(
+ "^((\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}\\2$"
+ );
+
+ private static final Pattern ipv6_p = Pattern.compile(
+ "^(([0-9a-fA-F]{0,4})([:|.])){2,7}([0-9a-fA-F]{0,4})$"
+ );
+
+ private static final Pattern doubleColon = Pattern.compile(
+ ".*::.*::.*"
+ );
+
+ private static final Pattern tooManyColon = Pattern.compile(
+ "(.*:){1,7}"
+ );
+
+
+ public static boolean ipv4(String str) {
+ return ipv4_p.matcher(str).matches();
+ }
+
+ public static boolean ipv6(String str) {
+ return ipv6_p.matcher(str).matches() &&
+ !doubleColon.matcher(str).matches() &&
+ !tooManyColon.matcher(str).matches();
+ }
+
+ public static boolean ip (String str) {
+ return ipv4_p.matcher(str).matches() || ipv6(str);
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/IndentPrintWriter.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/IndentPrintWriter.java
new file mode 100644
index 0000000..17cbff3
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/IndentPrintWriter.java
@@ -0,0 +1,114 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+/**
+ * @author Jonathan
+ *
+ * Catch \n and indent according to current indent levels of JavaGen
+ */
+public class IndentPrintWriter extends PrintWriter {
+ public static int INDENT = 2;
+ private boolean addIndent;
+ private int indent;
+ private int col;
+
+ public IndentPrintWriter(Writer out) {
+ super(out);
+ addIndent = false;
+ indent = col = 0;
+ }
+
+ public IndentPrintWriter(OutputStream out) {
+ super(out);
+ addIndent = false;
+ indent = col = 0;
+ }
+
+
+ public void write(String str) {
+ int len = str.length();
+ for(int i=0;i<len;++i) {
+ write((int)str.charAt(i));
+ }
+ }
+
+ public void println() {
+ write((int)'\n');
+ }
+ public void write(String str, int off, int len) {
+ len = Math.min(str.length(),off+len);
+ for(int i=off;i<len;++i) {
+ write((int)str.charAt(i));
+ }
+ }
+ public void write(int b) {
+ if (b == '\n') {
+ addIndent = true;
+ col = 0;
+ } else if (addIndent) {
+ addIndent = false;
+ toIndent();
+ } else {
+ ++col;
+ }
+ super.write(b);
+ }
+
+ @Override
+ public void write(char[] buf, int off, int len) {
+ for (int i = 0; i < len; ++i)
+ write(buf[i] + off);
+ }
+
+ public void setIndent(int size) {
+ indent = size;
+ }
+
+ public void inc() {
+ ++indent;
+ }
+
+ public void dec() {
+ --indent;
+ }
+
+ public void toCol(int idx) {
+ while(idx>col++)super.write((int)' ');
+ }
+
+ public int getIndent() {
+ return indent;
+ }
+
+ public void toIndent() {
+ int end = indent * INDENT;
+ for (int i = 0; i < end; ++i) {
+ super.write((int) ' ');
+ }
+ col = end;
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/Pool.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Pool.java
new file mode 100644
index 0000000..cd11dcb
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Pool.java
@@ -0,0 +1,398 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+/*
+ * Pool
+ *
+ * Author: Jonathan
+ * 5/27/2011
+ */
+package org.onap.aaf.misc.env.util;
+
+import java.util.LinkedList;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.LogTarget;
+
+/**
+ * This Class pools on an As-Needed-Basis any particular kind of class, which is
+ * quite suitable for expensive operations.
+ *
+ * The user calls "get" on a Pool, and if a waiting resource (T) is available,
+ * it will be returned. Otherwise, one will be created with the "Creator" class
+ * (must be defined for (T)).
+ *
+ * You can Prime the instances to avoid huge startup costs
+ *
+ * The returned "Pooled" object simply has to call "done()" and the object is
+ * returned to the pool. If the developer does not return the object, a memory
+ * leak does not occur. There are no references to the object once "get" is
+ * called. However, the developer who does not return the object when done
+ * obviates the point of the pool, as new Objects are created in place of the
+ * Object not returned when another call to "get" is made.
+ *
+ * There is a cushion of extra objects, currently defaulted to MAX_RANGE. If the
+ * items returned become higher than the MAX_RANGE, the object is allowed to go
+ * out of scope, and be cleaned up. the default can be changed on a per-pool
+ * basis.
+ *
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public class Pool<T> {
+ /**
+ * This is a constant which specified the default maximum number of unused
+ * objects to be held at any given time.
+ */
+ private static final int MAX_RANGE = 6; // safety
+
+ /**
+ * only Simple List needed.
+ *
+ * NOTE TO MAINTAINERS: THIS OBJECT DOES IT'S OWN SYNCHRONIZATION. All
+ * changes that touch list must account for correctly synchronizing list.
+ */
+ private LinkedList<Pooled<T>> list;
+
+ /**
+ * keep track of how many elements exist, to avoid asking list.
+ */
+ private int count;
+
+ /**
+ * Spares are those Object that are primed and ready to go.
+ */
+ private int spares;
+
+ /**
+ * Actual MAX number of spares allowed to hang around. Can be set to
+ * something besides the default MAX_RANGE.
+ */
+ private int max_range = MAX_RANGE;
+
+ /**
+ * The Creator for this particular pool. It must work for type T.
+ */
+ private Creator<T> creator;
+
+ /**
+ * Create a new Pool, given the implementation of Creator<T>, which must be
+ * able to create/destroy T objects at will.
+ *
+ * @param creator
+ */
+ public Pool(Creator<T> creator) {
+ count = spares = 0;
+ this.creator = creator;
+ list = new LinkedList<Pooled<T>>();
+ }
+
+ /**
+ * Preallocate a certain number of T Objects. Useful for services so that
+ * the first transactions don't get hit with all the Object creation costs
+ *
+ * @param lt
+ * @param prime
+ * @throws APIException
+ */
+ public void prime(LogTarget lt, int prime) throws APIException {
+ for (int i = 0; i < prime; ++i) {
+ Pooled<T> pt = new Pooled<T>(creator.create(), this, lt);
+ synchronized (list) {
+ list.addFirst(pt);
+ ++count;
+ }
+ }
+
+ }
+
+ /**
+ * Destroy and remove all remaining objects. This is valuable for closing
+ * down all Allocated objects cleanly for exiting. It is also a good method
+ * for removing objects when, for instance, all Objects are invalid because
+ * of broken connections, etc.
+ */
+ public void drain() {
+ synchronized (list) {
+ for (int i = 0; i < list.size(); ++i) {
+ Pooled<T> pt = list.remove();
+ creator.destroy(pt.content);
+ pt.logTarget.log("Pool drained ", creator.toString());
+ }
+ count = spares = 0;
+ }
+
+ }
+
+ /**
+ * This is the essential function for Pool. Get an Object "T" inside a
+ * "Pooled<T>" object. If there is a spare Object, then use it. If not, then
+ * create and pass back.
+ *
+ * This one uses a Null LogTarget
+ *
+ * IMPORTANT: When the use of this object is done (and the object is still
+ * in a valid state), then "done()" should be called immediately to allow
+ * the object to be reused. That is the point of the Pool...
+ *
+ * If the Object is in an invalid state, then "toss()" should be used so the
+ * Pool doesn't pass on invalid objects to others.
+ *
+ * @param lt
+ * @return
+ * @throws APIException
+ */
+ public Pooled<T> get() throws APIException {
+ Pooled<T> pt;
+ synchronized (list) {
+ if (list.isEmpty()) {
+ pt = null;
+ } else {
+ pt = list.removeLast();
+ --count;
+ creator.reuse(pt.content);
+ }
+ }
+ if (pt == null) {
+ if (spares < max_range)
+ ++spares;
+ pt = new Pooled<T>(creator.create(), this, LogTarget.NULL);
+ } else {
+ if (spares > 1)
+ --spares;
+ }
+ return pt;
+ }
+
+ /**
+ * This is the essential function for Pool. Get an Object "T" inside a
+ * "Pooled<T>" object. If there is a spare Object, then use it. If not, then
+ * create and pass back.
+ *
+ * If you don't have access to a LogTarget from Env, use LogTarget.NULL
+ *
+ * IMPORTANT: When the use of this object is done (and the object is still
+ * in a valid state), then "done()" should be called immediately to allow
+ * the object to be reused. That is the point of the Pool...
+ *
+ * If the Object is in an invalid state, then "toss()" should be used so the
+ * Pool doesn't pass on invalid objects to others.
+ *
+ * @param lt
+ * @return
+ * @throws APIException
+ */
+ public Pooled<T> get(LogTarget lt) throws APIException {
+ Pooled<T> pt;
+ synchronized (list) {
+ if (list.isEmpty()) {
+ pt = null;
+ } else {
+ pt = list.remove();
+ --count;
+ creator.reuse(pt.content);
+ }
+ }
+ if (pt == null) {
+ if (spares < max_range)
+ ++spares;
+ pt = new Pooled<T>(creator.create(), this, lt);
+ lt.log("Pool created ", creator.toString());
+ } else {
+ if (spares > 1)
+ --spares;
+ }
+ return pt;
+ }
+
+ /**
+ * This function will validate whether the Objects are still in a usable
+ * state. If not, they are tossed from the Pool. This is valuable to have
+ * when Remote Connections go down, and there is a question on whether the
+ * Pooled Objects are still functional.
+ *
+ * @return
+ */
+ public boolean validate() {
+ boolean rv = true;
+ synchronized (list) {
+ for (Pooled<T> t : list) {
+ if (!creator.isValid(t.content)) {
+ rv = false;
+ t.toss();
+ list.remove(t);
+ }
+ }
+ }
+ return rv;
+ }
+
+ /**
+ * This is an internal method, used only by the Internal Pooled<T> class.
+ *
+ * The Pooled<T> class "offers" it's Object back after use. It is an
+ * "offer", because Pool will simply destroy and remove the object if it has
+ * more than enough spares.
+ *
+ * @param lt
+ * @param used
+ * @return
+ */
+ // Used only by Pooled<T>
+ private boolean offer(LogTarget lt, Pooled<T> used) {
+ if (count < spares) {
+ synchronized (list) {
+ list.addFirst(used);
+ ++count;
+ }
+ lt.log("Pool recovered ", creator.toString());
+ } else {
+ lt.log("Pool destroyed ", creator.toString());
+ creator.destroy(used.content);
+ }
+ return false;
+ }
+
+ /**
+ * The Creator Interface give the Pool the ability to Create, Destroy and
+ * Validate the Objects it is maintaining. Thus, it is a specially written
+ * Implementation for each type.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+ public interface Creator<T> {
+ public T create() throws APIException;
+
+ public void destroy(T t);
+
+ public boolean isValid(T t);
+
+ public void reuse(T t);
+ }
+
+ /**
+ * The "Pooled<T>" class is the transient class that wraps the actual Object
+ * T for API use/ It gives the ability to return ("done()", or "toss()") the
+ * Object to the Pool when processing is finished.
+ *
+ * For Safety, i.e. to avoid memory leaks and invalid Object States, there
+ * is a "finalize" method. It is strictly for when coder forgets to return
+ * the object, or perhaps hasn't covered the case during Exceptions or
+ * Runtime Exceptions with finally (preferred). This should not be
+ * considered normal procedure, as finalize() is called at an undetermined
+ * time during garbage collection, and is thus rather useless for a Pool.
+ * However, we don't want Coding Mistakes to put the whole program in an
+ * invalid state, so if something happened such that "done()" or "toss()"
+ * were not called, the resource is still cleaned up as well as possible.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+ public static class Pooled<T> {
+ public final T content;
+ private Pool<T> pool;
+ protected LogTarget logTarget;
+
+ /**
+ * Create the Wrapping Object Pooled<T>.
+ *
+ * @param t
+ * @param pool
+ * @param logTarget
+ */
+ public Pooled(T t, Pool<T> pool, LogTarget logTarget) {
+ content = t;
+ this.pool = pool;
+ this.logTarget = logTarget;
+ }
+
+ /**
+ * This is the key API for the Pool, as calling "done()" offers this
+ * object back to the Pool for reuse.
+ *
+ * Do not use the Pooled<T> object again after calling "done()".
+ */
+ public void done() {
+ if (pool != null) {
+ pool.offer(logTarget, this);
+ }
+ }
+
+ /**
+ * The user of the Object may discover that the Object t is no longer in
+ * a valid state. Don't put Garbage back in the Refrigerator... Toss it,
+ * if it's no longer valid.
+ *
+ * toss() is also used for draining the Pool, etc.
+ *
+ * toss() will attempt to destroy the Object by using the Creator
+ * Interface.
+ *
+ */
+ public void toss() {
+ if (pool != null) {
+ pool.creator.destroy(content);
+ }
+ // Don't allow finalize to put it back in.
+ pool = null;
+ }
+
+ /**
+ * Just in case someone neglected to offer back object... Do not rely on
+ * this, as there is no specific time when finalize is called, which
+ * rather defeats the purpose of a Pool.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ if (pool != null) {
+ done();
+ pool = null;
+ }
+ }
+ }
+
+ /**
+ * Get the maximum number of spare objects allowed at any moment
+ *
+ * @return
+ */
+ public int getMaxRange() {
+ return max_range;
+ }
+
+ /**
+ * Set a Max Range for numbers of spare objects waiting to be used.
+ *
+ * No negative numbers are allowed
+ *
+ * @return
+ */
+ public void setMaxRange(int max_range) {
+ // Do not allow negative numbers
+ this.max_range = Math.max(0, max_range);
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/RefreshableThreadObject.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/RefreshableThreadObject.java
new file mode 100644
index 0000000..5615339
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/RefreshableThreadObject.java
@@ -0,0 +1,124 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Creatable;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LifeCycle;
+
+
+/**
+ * <h1>RefreshableThreadObject</h1>
+ * This is a ThreadLocal like implementation, but it responds to
+ * the {@link LifeCycle} mechanism for configuration refreshes, and
+ * implements {@link Creatable} (for use in destroy, etc).<p>
+ *
+ * In addition to the Thread instance semantics, it compares when the object
+ * was created versus the last "refresh(env)" call when getting, for the
+ * thread, and if necessary to replace the created object, destroying the
+ * previous.<p>
+ *
+ * In most cases, it's better to use the new "Pool" mechanism, as it deals with
+ * gaining and returning resources on an as needed basis. This, however, remains
+ * in the cases where specific Objects need to be retained to specific Threads.<p>
+ *
+ * There is no way to do this kind of specialized behavior in ThreadLocal.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public class RefreshableThreadObject<T extends Creatable<T>> {
+ private Map<Thread,T> objs;
+ private long refreshed;
+ private Constructor<T> cnst;
+
+ /**
+ * The passed in class <b>must</b> implement the constructor
+ * <pre>
+ * public MyClass(Env env) {
+ * ...
+ * }
+ * </pre>
+ * @param clss
+ * @throws APIException
+ */
+ public RefreshableThreadObject(Class<T> clss) throws APIException {
+ objs = new ConcurrentHashMap<Thread,T>();
+ try {
+ cnst = clss.getConstructor(new Class[]{Env.class} );
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+ /**
+ * Get the "T" class from the current thread
+ *
+ * @param env
+ * @return T
+ * @throws APIException
+ */
+ public T get(Env env) throws APIException {
+ Thread t = Thread.currentThread();
+ T obj = objs.get(t);
+ if(obj==null || refreshed>obj.created()) {
+ try {
+ obj = cnst.newInstance(new Object[]{env});
+ } catch (InvocationTargetException e) {
+ throw new APIException(e.getTargetException());
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ T destroyMe = objs.put(t,obj);
+ if(destroyMe!=null) {
+ destroyMe.destroy(env);
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * Mark the timestamp of refreshed.
+ *
+ * @param env
+ */
+ public void refresh(Env env) {
+ refreshed = System.currentTimeMillis();
+ }
+
+ /**
+ * Remove the object from the Thread instances
+ * @param env
+ */
+ public void remove(Env env) {
+ T obj = objs.remove(Thread.currentThread());
+ if(obj!=null)
+ obj.destroy(env);
+ }
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/Split.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Split.java
new file mode 100644
index 0000000..79a7403
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/Split.java
@@ -0,0 +1,89 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+/**
+ * Split by Char, optional Trim
+ *
+ * Note: I read the String split and Pattern split code, and we can do this more efficiently for a single Character
+ *
+ * Jonathan 8/20/2015
+ */
+
+public class Split {
+ public static String[] split(char c, String value) {
+ // Count items to preallocate Array (memory alloc is more expensive than counting twice)
+ int count,idx;
+ for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count);
+ String[] rv = new String[count];
+ if(count==1) {
+ rv[0]=value;
+ } else {
+ int last=0;
+ count=-1;
+ for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) {
+ rv[++count]=value.substring(last,idx);
+ last = ++idx;
+ }
+ rv[++count]=value.substring(last);
+ }
+ return rv;
+ }
+
+ public static String[] splitTrim(char c, String value) {
+ // Count items to preallocate Array (memory alloc is more expensive than counting twice)
+ int count,idx;
+ for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count);
+ String[] rv = new String[count];
+ if(count==1) {
+ rv[0]=value.trim();
+ } else {
+ int last=0;
+ count=-1;
+ for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) {
+ rv[++count]=value.substring(last,idx).trim();
+ last = ++idx;
+ }
+ rv[++count]=value.substring(last).trim();
+ }
+ return rv;
+ }
+
+ public static String[] splitTrim(char c, String value, int size) {
+ int idx;
+ String[] rv = new String[size];
+ if(size==1) {
+ rv[0]=value.trim();
+ } else {
+ int last=0;
+ int count=-1;
+ size-=2;
+ for(idx=value.indexOf(c);idx>=0 && count<size;idx=value.indexOf(c,idx)) {
+ rv[++count]=value.substring(last,idx).trim();
+ last = ++idx;
+ }
+ rv[++count]=value.substring(last).trim();
+ }
+ return rv;
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderOutputStream.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderOutputStream.java
new file mode 100644
index 0000000..c2a1f91
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderOutputStream.java
@@ -0,0 +1,178 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class StringBuilderOutputStream extends OutputStream {
+ private StringBuilder buf;
+
+
+ /**
+ * Create a new string writer using the default initial string-buffer
+ * size.
+ */
+ public StringBuilderOutputStream() {
+ buf = new StringBuilder();
+ }
+
+ /**
+ * Create a new string writer using a passed in StringBuilder
+ * size.
+ */
+ public StringBuilderOutputStream(StringBuilder sb) {
+ buf = sb;
+ }
+
+ /**
+ * Create a new string writer using the specified initial string-buffer
+ * size.
+ *
+ * @param initialSize
+ * The number of <tt>byte</tt> values that will fit into this buffer
+ * before it is automatically expanded
+ *
+ * @throws IllegalArgumentException
+ * If <tt>initialSize</tt> is negative
+ */
+ public StringBuilderOutputStream(int initialSize) {
+ if (initialSize < 0) {
+ throw new IllegalArgumentException("Negative buffer size");
+ }
+ buf = new StringBuilder(initialSize);
+ }
+
+ /**
+ * Write a single character.
+ */
+ public void write(int c) {
+ buf.append((byte) c);
+ }
+
+ /**
+ * Write a portion of an array of characters.
+ *
+ * @param bbuf Array of characters
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+
+ public void write(byte bbuf[], int off, int len) {
+ if ((off < 0) || (off > bbuf.length) || (len < 0) ||
+ ((off + len) > bbuf.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ buf.append(new String(bbuf, off, len));
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ buf.append(new String(b));
+ }
+
+ /**
+ * Write a string.
+ */
+ public void write(String str) {
+ buf.append(str);
+ }
+
+ /**
+ * Write a portion of a string.
+ *
+ * @param str String to be written
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+ public void write(String str, int off, int len) {
+ buf.append(str,off,len);
+ }
+
+ public StringBuilderOutputStream append(CharSequence csq) {
+ if (csq == null) {
+ write("null");
+ } else {
+ for(int i = 0;i<csq.length();++i) {
+ buf.append(csq.charAt(i));
+ }
+ }
+ return this;
+ }
+
+ public StringBuilderOutputStream append(CharSequence csq, int start, int end) {
+ CharSequence cs = (csq == null ? "null" : csq);
+ return append(cs.subSequence(start, end));
+ }
+
+ /**
+ * Appends the specified character to this writer.
+ *
+ * <p> An invocation of this method of the form <tt>out.append(c)</tt>
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * out.write(c) </pre>
+ *
+ * @param c
+ * The 16-bit character to append
+ *
+ * @return This writer
+ *
+ * @since 1.5
+ */
+ public StringBuilderOutputStream append(byte c) {
+ buf.append(c);
+ return this;
+ }
+
+ /**
+ * Return the buffer's current value as a string.
+ */
+ public String toString() {
+ return buf.toString();
+ }
+
+ /**
+ * Return the string buffer itself.
+ *
+ * @return StringBuffer holding the current buffer value.
+ */
+ public StringBuilder getBuffer() {
+ return buf;
+ }
+
+ public void reset() {
+ buf.setLength(0);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+}
diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderWriter.java b/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderWriter.java
new file mode 100644
index 0000000..cea4d85
--- /dev/null
+++ b/misc/env/src/main/java/org/onap/aaf/misc/env/util/StringBuilderWriter.java
@@ -0,0 +1,172 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class StringBuilderWriter extends Writer {
+ private StringBuilder buf;
+
+
+ /**
+ * Create a new string writer using the default initial string-buffer
+ * size.
+ */
+ public StringBuilderWriter() {
+ buf = new StringBuilder();
+ }
+
+ /**
+ * Create a new string writer using a passed in StringBuilder
+ * size.
+ */
+ public StringBuilderWriter(StringBuilder sb) {
+ buf = sb;
+ }
+
+ /**
+ * Create a new string writer using the specified initial string-buffer
+ * size.
+ *
+ * @param initialSize
+ * The number of <tt>char</tt> values that will fit into this buffer
+ * before it is automatically expanded
+ *
+ * @throws IllegalArgumentException
+ * If <tt>initialSize</tt> is negative
+ */
+ public StringBuilderWriter(int initialSize) {
+ if (initialSize < 0) {
+ throw new IllegalArgumentException("Negative buffer size");
+ }
+ buf = new StringBuilder(initialSize);
+ }
+
+ /**
+ * Write a single character.
+ */
+ public void write(int c) {
+ buf.append((char) c);
+ }
+
+ /**
+ * Write a portion of an array of characters.
+ *
+ * @param cbuf Array of characters
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+ public void write(char cbuf[], int off, int len) {
+ if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+ ((off + len) > cbuf.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ buf.append(cbuf, off, len);
+ }
+
+ /**
+ * Write a string.
+ */
+ public void write(String str) {
+ buf.append(str);
+ }
+
+ /**
+ * Write a portion of a string.
+ *
+ * @param str String to be written
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+ public void write(String str, int off, int len) {
+ char[] chars = new char[len];
+ str.getChars(off, off+len, chars, 0);
+ buf.append(chars);
+ }
+
+ public StringBuilderWriter append(CharSequence csq) {
+ if (csq == null) {
+ write("null");
+ } else {
+ buf.append(csq);
+ }
+ return this;
+ }
+
+ public StringBuilderWriter append(CharSequence csq, int start, int end) {
+ CharSequence cs = (csq == null ? "null" : csq);
+ return append(cs.subSequence(start, end));
+ }
+
+ /**
+ * Appends the specified character to this writer.
+ *
+ * <p> An invocation of this method of the form <tt>out.append(c)</tt>
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * out.write(c) </pre>
+ *
+ * @param c
+ * The 16-bit character to append
+ *
+ * @return This writer
+ *
+ * @since 1.5
+ */
+ public StringBuilderWriter append(char c) {
+ buf.append(c);
+ return this;
+ }
+
+ /**
+ * Return the buffer's current value as a string.
+ */
+ public String toString() {
+ return buf.toString();
+ }
+
+ /**
+ * Return the string buffer itself.
+ *
+ * @return StringBuffer holding the current buffer value.
+ */
+ public StringBuilder getBuffer() {
+ return buf;
+ }
+
+ public void reset() {
+ buf.setLength(0);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+}
diff --git a/misc/env/src/test/java/org/onap/aaf/misc/env/util/test/JU_IPValidator.java b/misc/env/src/test/java/org/onap/aaf/misc/env/util/test/JU_IPValidator.java
new file mode 100644
index 0000000..01acf21
--- /dev/null
+++ b/misc/env/src/test/java/org/onap/aaf/misc/env/util/test/JU_IPValidator.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.util.test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.util.IPValidator;
+
+public class JU_IPValidator {
+
+ @Test
+ public void test() {
+ assertTrue(IPValidator.ipv4("10.10.10.10"));
+ assertTrue(IPValidator.ipv4("127.0.0.0"));
+ assertFalse(IPValidator.ipv4("10"));
+ assertFalse(IPValidator.ipv4("10.10.10"));
+ assertFalse(IPValidator.ipv4("10.10.10."));
+ assertFalse(IPValidator.ipv4("10.10.10.10."));
+ assertFalse(IPValidator.ipv4("10.10.10.10.10"));
+ assertFalse(IPValidator.ipv4("something10.10.10.10"));
+ assertTrue(IPValidator.ipv4("0.10.10.10"));
+ assertTrue(IPValidator.ipv4("0.0.0.0"));
+ assertTrue(IPValidator.ipv4("0.10.10.10"));
+ assertFalse(IPValidator.ipv4("011.255.255.255"));
+ assertFalse(IPValidator.ipv4("255.01.255.255"));
+ assertFalse(IPValidator.ipv4("255.255.255.256"));
+ assertFalse(IPValidator.ipv4("255.299.255.255"));
+
+
+ assertTrue(IPValidator.ipv6("0000:0000:0000:0000:0000:0000:0000:0000"));
+ assertTrue(IPValidator.ipv6("0:0:0:0:0:0:0:0"));
+ assertTrue(IPValidator.ipv6("2001:08DB:0000:0000:0023:F422:FE3B:AC10"));
+ assertTrue(IPValidator.ipv6("2001:8DB:0:0:23:F422:FE3B:AC10"));
+ assertTrue(IPValidator.ipv6("2001:8DB::23:F422:FE3B:AC10"));
+ assertTrue(IPValidator.ipv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
+ assertTrue(IPValidator.ipv6("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"));
+ assertFalse(IPValidator.ipv6("2001:8DB::23:G422:FE3B:AC10"));
+ assertFalse(IPValidator.ipv6("2001:8DB::23:G422:FE3B:AC10"));
+ // more than one Double Colons
+ assertFalse(IPValidator.ipv6("0000:0000:0000::0000::0000"));
+ assertFalse(IPValidator.ipv6("2001:8DB::23:G422:FE3B:AC10:FFFF"));
+
+
+
+ assertTrue(IPValidator.ip("2001:08DB:0000:0000:0023:F422:FE3B:AC10"));
+ assertTrue(IPValidator.ip("192.168.7.2"));
+ }
+
+}
diff --git a/misc/log4j/.gitignore b/misc/log4j/.gitignore
new file mode 100644
index 0000000..45aeec6
--- /dev/null
+++ b/misc/log4j/.gitignore
@@ -0,0 +1,5 @@
+/target/
+/.settings/
+/.classpath
+/logs/
+/.project
diff --git a/misc/log4j/pom.xml b/misc/log4j/pom.xml
new file mode 100644
index 0000000..facb2f7
--- /dev/null
+++ b/misc/log4j/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aaf-misc-log4j</artifactId>
+ <name>AAF Misc Log4J</name>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>aaf-misc-env</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.java.dev.jna</groupId>
+ <artifactId>jna-platform</artifactId>
+ <version>4.0.0</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java
new file mode 100644
index 0000000..a8830b4
--- /dev/null
+++ b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java
@@ -0,0 +1,81 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.log4j;
+
+import java.io.File;
+import java.net.URL;
+
+public class LogFileNamer {
+ public static final int pid = PIDAccess.INSTANCE.getpid();
+ public final String root;
+ private boolean printPID;
+
+ public LogFileNamer(String root) {
+ if(root==null || "".equals(root) || root.endsWith("/")) {
+ this.root = root;
+ } else {
+ this.root = root + "-";
+ }
+ printPID=true;
+ }
+
+ public LogFileNamer noPID() {
+ printPID = false;
+ return this;
+ }
+ /**
+ * Accepts a String.
+ * If Separated by "|" then first part is the Appender name, and the second is used in the FileNaming
+ * (This is to allow for shortened Logger names, and more verbose file names)
+ *
+ * @param appender
+ *
+ * returns the String Appender
+ */
+ public String setAppender(String appender) {
+ int pipe = appender.indexOf('|');
+ if(pipe>=0) {
+ String rv;
+ System.setProperty(
+ "LOG4J_FILENAME_"+(rv=appender.substring(0,pipe)),
+ root + appender.substring(pipe+1) + (printPID?('-' + pid):"") + ".log");
+ return rv;
+ } else {
+ System.setProperty(
+ "LOG4J_FILENAME_"+appender,
+ root + appender + (printPID?('-' + pid):"") + ".log");
+ return appender;
+ }
+
+ }
+
+ public void configure(String props) {
+ String fname;
+ if(new File(fname="etc/"+props).exists()) {
+ org.apache.log4j.PropertyConfigurator.configureAndWatch(fname,60*1000);
+ } else {
+ URL rsrc = ClassLoader.getSystemResource(props);
+ if(rsrc==null) System.err.println("Neither File: " + fname + " or resource on Classpath " + props + " exist" );
+ org.apache.log4j.PropertyConfigurator.configure(rsrc);
+ }
+ }
+}
diff --git a/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/PIDAccess.java b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/PIDAccess.java
new file mode 100644
index 0000000..6e23ce6
--- /dev/null
+++ b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/PIDAccess.java
@@ -0,0 +1,30 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.log4j;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
+public interface PIDAccess extends Library {
+ PIDAccess INSTANCE = (PIDAccess) Native.loadLibrary("c", PIDAccess.class);
+ int getpid ();
+}
diff --git a/misc/log4j/src/test/java/org/onap/aaf/misc/env/log4j/LogTest.java b/misc/log4j/src/test/java/org/onap/aaf/misc/env/log4j/LogTest.java
new file mode 100644
index 0000000..d5c9062
--- /dev/null
+++ b/misc/log4j/src/test/java/org/onap/aaf/misc/env/log4j/LogTest.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.env.log4j;
+
+import java.util.logging.Logger;
+
+import org.onap.aaf.misc.env.log4j.LogFileNamer;
+
+
+public class LogTest
+{
+ public static void main(String[] args) throws Exception
+ {
+ LogFileNamer lfn = new LogFileNamer("authz");
+ lfn.setAppender("service");
+ lfn.setAppender("init");
+ lfn.setAppender("audit");
+ lfn.setAppender("test");
+ lfn.configure("src/test/resources/log4j-test.properties");
+ Logger log = Logger.getLogger( "init" );
+
+
+
+ log.info("Hello");
+ }
+}
diff --git a/misc/log4j/src/test/resources/.gitignore b/misc/log4j/src/test/resources/.gitignore
new file mode 100644
index 0000000..2079777
--- /dev/null
+++ b/misc/log4j/src/test/resources/.gitignore
@@ -0,0 +1 @@
+/log4j-test.properties
diff --git a/misc/pom.xml b/misc/pom.xml
new file mode 100644
index 0000000..4eba2fd
--- /dev/null
+++ b/misc/pom.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>parent</artifactId>
+ <name>AAF Misc Parent</name>
+ <version>1.3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <powermock.version>1.5.1</powermock.version>
+ </properties>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.10</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <version>2.4</version>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <outputDirectory>target</outputDirectory>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <inherited>true</inherited>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <distributionManagement>
+ <repository>
+ <id>nexus</id>
+ <name>attarch-releases</name>
+ <url>http://mavencentral.it.att.com:8084/nexus/content/repositories/attarch-releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>nexus</id>
+ <name>attarch-snapshots</name>
+ <url>http://mavencentral.it.att.com:8084/nexus/content/repositories/attarch-snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <modules>
+ <module>env</module>
+ <module>xgen</module>
+ <module>rosetta</module>
+ <module>log4j</module> <!-- note: generates log4j, to avoid Jar conflict -->
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.17</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.5</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/misc/rosetta/.gitignore b/misc/rosetta/.gitignore
new file mode 100644
index 0000000..3b314b8
--- /dev/null
+++ b/misc/rosetta/.gitignore
@@ -0,0 +1,6 @@
+/target/
+/.classpath
+/.settings/
+/logs/
+/target/
+/.project
diff --git a/misc/rosetta/pom.xml b/misc/rosetta/pom.xml
new file mode 100644
index 0000000..1f3c149
--- /dev/null
+++ b/misc/rosetta/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aaf-misc-rosetta</artifactId>
+ <name>AAF Misc Rosetta</name>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>aaf-misc-env</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+ <version>0.8.2</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <schemaDirectory>src/main/xsd</schemaDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InJson.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InJson.java
new file mode 100644
index 0000000..725389c
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InJson.java
@@ -0,0 +1,154 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.rosetta.InJson.State;
+
+public class InJson implements Parse<Reader, State> {
+ public Parsed<State> parse(Reader r, Parsed<State> parsed) throws ParseException {
+ // First things first, if there's a "leftover" event, process that immediately
+ State state = (State)parsed.state;
+ if(state.unsent > 0) {
+ parsed.event = state.unsent;
+ state.unsent = 0;
+ return parsed;
+ }
+
+ int ch;
+ char c;
+ StringBuilder sb = parsed.sb;
+ boolean inQuotes = false, escaped = false;
+ boolean go = true;
+ try {
+ // Gather data from Reader, looking for special characters when not in Quotes
+ while(go && (ch=r.read())>=0) {
+ if(state.braces>=0 || ch==Parse.START_OBJ) { // ignore garbage/whitespace before content
+ c=(char)ch;
+ // Character is a quote.
+ if(c=='"') {
+ if(inQuotes) {
+ if(escaped) { // if escaped Quote, add to data.
+ sb.append(c);
+ escaped = false;
+ } else {
+ inQuotes = false;
+ }
+ } else {
+ parsed.isString=true;
+ inQuotes = true;
+ }
+ } else { // Not a Quote
+ if(inQuotes) {
+ if(c=='\\') {
+ if(escaped) {
+ sb.append("\\\\");
+ escaped = false;
+ } else {
+ escaped = true;
+ }
+ } else {
+ sb.append(c);
+ }
+ } else {
+ switch(c) {
+ case ':':
+ parsed.dataIsName();
+ parsed.isString = false;
+ break;
+ case Parse.START_OBJ:
+ if(state.braces++ == 0) {
+ parsed.event = START_DOC;
+ state.unsent = c;
+ } else {
+ parsed.event = c;
+ }
+ go = false;
+ break;
+ case Parse.END_OBJ:
+ if(--state.braces == 0) {
+ parsed.event = c;
+ state.unsent = END_DOC;
+ } else {
+ parsed.event = c;
+ }
+ go = false;
+ break;
+ // These three end the data gathering, and send it along with the event that is ending the data gathering
+ case Parse.NEXT:
+ if(parsed.name.startsWith("__")) {
+ parsed.event = Parse.ATTRIB;
+ parsed.name = parsed.name.substring(2);
+ } else {
+ parsed.event = c;
+ }
+ go = false;
+ break;
+ case Parse.START_ARRAY:
+ case Parse.END_ARRAY:
+ parsed.event = c;
+ go = false;
+ break;
+
+ // The Escape Sequence, for Quote marks within Quotes
+ case '\\':
+ // Ignore these, unless within quotes, at which point data-gather
+ case ' ':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ break;
+ // Normal data... gather it
+ default:
+ sb.append(c);
+ }
+ }
+ }
+ }
+ }
+ return parsed;
+ } catch (IOException e) {
+ throw new ParseException(e);
+ }
+ }
+
+ public static class State {
+ public int braces = 0;
+ public char unsent = 0;
+ }
+
+// @Override
+ public Parsed<State> newParsed() {
+ return new Parsed<State>(new State()); // no State needed
+ }
+
+// @Override
+ public TimeTaken start(Env env) {
+ return env.start("Rosetta JSON In", Env.JSON);
+ }
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InXML.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InXML.java
new file mode 100644
index 0000000..5192657
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/InXML.java
@@ -0,0 +1,486 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.rosetta.InXML.State;
+
+public class InXML implements Parse<Reader, State> {
+ // package on purpose
+ JaxInfo jaxInfo;
+
+ public InXML(JaxInfo jaxInfo) {
+ this.jaxInfo = jaxInfo;
+ }
+
+ public InXML(Class<?> cls, String ... rootNs) throws SecurityException, NoSuchFieldException, ClassNotFoundException, ParseException {
+ jaxInfo = JaxInfo.build(cls,rootNs);
+ }
+
+
+ // @Override
+ public Parsed<State> parse(Reader r, Parsed<State> parsed) throws ParseException {
+ State state = parsed.state;
+
+ // OK, before anything else, see if there is leftover processing, if so, do it!
+ if(state.unevaluated!=null) {
+ DerTag dt = state.unevaluated;
+ state.unevaluated = null;
+ if(!state.greatExp.eval(parsed, dt))return parsed;
+ }
+
+ if(state.hasAttributes()) {
+ Prop prop = state.pop();
+ parsed.event = Parse.ATTRIB;
+ parsed.name = prop.tag;
+ parsed.sb.append(prop.value);
+ parsed.isString=true;
+ return parsed;
+ }
+ int ch;
+ char c;
+ boolean inQuotes = false, escaped = false;
+
+ StringBuilder sb = parsed.sb, tempSB = new StringBuilder();
+ boolean go = true;
+
+ try {
+ while(go && (ch=r.read())>=0) {
+ c = (char)ch;
+ if(c == '"') {
+ if(state.greatExp instanceof LeafExpectations) { // within a set of Tags, make a Quote
+ sb.append(c);
+ } else {
+ if(inQuotes) {
+ if(escaped) {
+ sb.append('\\');
+ sb.append(c);
+ escaped = false;
+ } else {
+ inQuotes = false;
+ }
+ } else {
+ parsed.isString=true;
+ inQuotes = true;
+ }
+ }
+ } else if(inQuotes) {
+ sb.append(c);
+ } else if(c=='&') {
+ XmlEscape.xmlEscape(sb,r);
+ } else {
+ switch(c) {
+ case '<':
+ DerTag tag=new DerTag().parse(r, tempSB);
+ go = state.greatExp.eval(parsed, tag);
+ break;
+ default:
+ // don't add Whitespace to start of SB... saves removing later
+ if(sb.length()>0) {
+ sb.append(c);
+ } else if(!Character.isWhitespace(c)) {
+ sb.append(c);
+ }
+ }
+ }
+ }
+ return parsed;
+ } catch (IOException e) {
+ throw new ParseException(e);
+ }
+ }
+
+ public static final class DerTag {
+ public String name;
+ public boolean isEndTag;
+ public List<Prop> props;
+ private boolean isXmlInfo;
+ //private String ns;
+
+ public DerTag() {
+ name=null;
+ isEndTag = false;
+ props = null;
+ isXmlInfo = false;
+ }
+
+ public DerTag parse(Reader r, StringBuilder sb) throws ParseException {
+ int ch;
+ char c;
+ boolean inQuotes = false, escaped = false;
+ boolean go = true;
+ String tag = null;
+
+ try {
+ if((ch = r.read())<0) throw new ParseException("Reader content ended before complete");
+ if(ch=='?') {
+ isXmlInfo = true;
+ }
+ // TODO Check for !-- comments
+ do {
+ c=(char)ch;
+ if(c=='"') {
+ if(inQuotes) {
+ if(escaped) {
+ sb.append(c);
+ escaped = false;
+ } else {
+ inQuotes = false;
+ }
+ } else {
+ inQuotes = true;
+ }
+ } else if(inQuotes) {
+ sb.append(c);
+ } else {
+ switch(c) {
+ case '/':
+ isEndTag = true;
+ break;
+ case ' ':
+ endField(tag,sb);
+ tag = null;
+ break;
+ case '>':
+ endField(tag,sb);
+ go = false;
+ break;
+ case '=':
+ tag = sb.toString();
+ sb.setLength(0);
+ break;
+// case ':':
+// ns = sb.toString();
+// sb.setLength(0);
+// break;
+ case '?':
+ if(!isXmlInfo)sb.append(c);
+ break;
+ default:
+ sb.append(c);
+ }
+ }
+ } while(go && (ch=r.read())>=0);
+ } catch (IOException e) {
+ throw new ParseException(e);
+ }
+ return this;
+ }
+
+ private void endField(String tag, StringBuilder sb) {
+ if(name==null) {
+ name = sb.toString();
+ sb.setLength(0);
+ } else {
+ String value = sb.toString();
+ sb.setLength(0);
+ if(tag !=null && value != null) {
+ if(props==null)props = new ArrayList<Prop>();
+ props.add(new Prop(tag,value));
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(isEndTag?"End":"Start");
+ sb.append(" Tag\n");
+ sb.append(" Name: ");
+ sb.append(name);
+ if(props!=null) for(Prop p : props) {
+ sb.append("\n ");
+ sb.append(p.tag);
+ sb.append("=\"");
+ sb.append(p.value);
+ sb.append('"');
+ }
+ return sb.toString();
+ }
+ }
+
+ private static class ArrayState {
+ public boolean firstObj = true;
+ public boolean didNext = false;
+ }
+
+ public static class State {
+ public GreatExpectations greatExp;
+ public DerTag unevaluated;
+ public Stack<ArrayState> arrayInfo;
+ private List<Prop> attribs;
+ private int idx;
+ public State(JaxInfo ji, DerTag dt) throws ParseException {
+ greatExp = new RootExpectations(this, ji, null);
+ unevaluated = null;
+ attribs = null;;
+ }
+
+ public boolean hasAttributes() {
+ return attribs!=null && idx<attribs.size();
+ }
+
+ public void push(Prop prop) {
+ if(attribs==null) {
+ attribs = new ArrayList<Prop>();
+ idx = 0;
+ }
+ attribs.add(prop);
+ }
+
+ public Prop pop() {
+ Prop rv = null;
+ if(attribs!=null) {
+ rv = attribs.get(idx++);
+ if(idx>=attribs.size())attribs = null;
+ }
+ return rv;
+ }
+ }
+
+ private static abstract class GreatExpectations {
+ protected JaxInfo ji;
+ protected GreatExpectations prev;
+ private Map<String,String> ns;
+
+ public GreatExpectations(State state, JaxInfo curr, GreatExpectations prev, DerTag derTag) throws ParseException {
+ this.prev = prev;
+ ns = null;
+ ji = getDerived(state, curr,derTag);
+ }
+
+ public abstract boolean eval(Parsed<State> parsed, DerTag derTag) throws ParseException;
+
+ // Recursively look back for any namespaces
+ protected Map<String,String> getNS() {
+ if(ns!=null)return ns;
+ if(prev!=null) {
+ return prev.getNS();
+ }
+ return null;
+ }
+
+ private void addNS(Prop prop) {
+ Map<String,String> existingNS = getNS();
+ if(ns==null)ns = new HashMap<String,String>();
+ // First make a copy of previous NSs so that we have everything we need, but can overwrite, if necessary
+ if(existingNS!=null && ns!=existingNS) {
+ ns.putAll(ns);
+ }
+ ns.put(prop.tag, prop.value);
+ }
+
+ private JaxInfo getDerived(State state, JaxInfo ji, DerTag derTag) throws ParseException {
+ if(derTag==null)return ji;
+
+ List<Prop> props = derTag.props;
+
+ Prop derived = null;
+ if(props!=null) {
+ // Load Namespaces (if any)
+ for(Prop prop : props) {
+ if(prop.tag.startsWith("xmlns:")) {
+ addNS(prop);
+ }
+ }
+ for(Prop prop : props) {
+ if(prop.tag.endsWith(":type")) {
+ int idx = prop.tag.indexOf(':');
+ String potentialNS = "xmlns:"+prop.tag.substring(0,idx);
+ Map<String,String> ns = getNS();
+ boolean noNamespace = false;
+ if(ns==null) {
+ noNamespace = true;
+ } else {
+ String nsVal = ns.get(potentialNS);
+ if(nsVal==null) noNamespace = true;
+ else {
+ derived = new Prop(Parsed.EXTENSION_TAG,prop.value);
+ state.push(derived);
+ }
+ }
+ if(noNamespace) {
+ throw new ParseException(prop.tag + " utilizes an invalid Namespace prefix");
+ }
+ } else if(!prop.tag.startsWith("xmlns")) {
+ state.push(prop);
+ }
+ }
+ }
+ return derived==null?ji:ji.getDerived(derived.value);
+ }
+ }
+
+ private static class RootExpectations extends GreatExpectations {
+
+ public RootExpectations(State state, JaxInfo curr, GreatExpectations prev) throws ParseException {
+ super(state,curr,prev, null);
+ }
+
+ // @Override
+ public boolean eval(Parsed<State> parsed, DerTag derTag) throws ParseException {
+ if(derTag.isXmlInfo) {
+ parsed.event = START_DOC;
+ } else if(ji.name.equals(derTag.name)) {
+ if(derTag.isEndTag) {
+ parsed.event = END_DOC;
+ parsed.state.greatExp = prev;
+ } else {
+ //parsed.name = derTag.name;
+ parsed.event = START_OBJ;
+ parsed.state.greatExp = new ObjectExpectations(parsed.state,ji, this, false, derTag);
+ }
+ }
+ return false;
+ }
+ }
+
+ private static class ObjectExpectations extends GreatExpectations {
+ private boolean printName;
+
+ public ObjectExpectations(State state, JaxInfo curr, GreatExpectations prev, boolean printName, DerTag derTag) throws ParseException {
+ super(state, curr, prev, derTag);
+ this.printName=printName;
+ }
+
+ // @Override
+ public boolean eval(Parsed<State> parsed, DerTag derTag) throws ParseException {
+ if(derTag.isEndTag && ji.name.equals(derTag.name)) {
+ parsed.state.greatExp = prev;
+ parsed.event = END_OBJ;
+ if(printName)parsed.name = ji.name;
+ } else {
+ //Standard Members
+ for(JaxInfo memb : ji.members) {
+ if(memb.name.equals(derTag.name)) {
+ parsed.name = memb.name;
+ if(memb.isArray) {
+ parsed.state.unevaluated = derTag; // evaluate within Array Context
+ parsed.event = START_ARRAY;
+ parsed.state.greatExp = new ArrayExpectations(parsed.state,memb,this);
+ return false;
+ } else if(memb.isObject()) {
+ if(derTag.isEndTag) {
+ throw new ParseException("Unexpected End Tag </" + derTag.name + '>');
+ } else {
+ parsed.event = START_OBJ;
+
+ parsed.state.greatExp = new ObjectExpectations(parsed.state, memb,this,true,derTag);
+ return false;
+ }
+ } else { // a leaf
+ if(derTag.isEndTag) {
+ throw new ParseException("Misplaced End Tag </" + parsed.name + '>');
+ } else {
+ parsed.state.greatExp = new LeafExpectations(parsed.state,memb, this);
+ return true; // finish out Leaf without returning
+ }
+ }
+ }
+ }
+
+ throw new ParseException("Unexpected Tag <" + derTag.name + '>');
+ }
+ return false;
+ }
+ }
+
+ private static class LeafExpectations extends GreatExpectations {
+ public LeafExpectations(State state, JaxInfo curr, GreatExpectations prev) throws ParseException {
+ super(state, curr, prev, null);
+ }
+
+ // @Override
+ public boolean eval(Parsed<State> parsed, DerTag derTag) throws ParseException {
+ if(ji.name.equals(derTag.name) && derTag.isEndTag) {
+ parsed.event = NEXT;
+ parsed.isString = ji.isString;
+ parsed.state.greatExp = prev;
+ } else {
+ throw new ParseException("Expected </" + ji.name + '>');
+ }
+ return false;
+ }
+ }
+
+ private static class ArrayExpectations extends GreatExpectations {
+ public ArrayExpectations(State state, JaxInfo ji, GreatExpectations prev) throws ParseException {
+ super(state, ji, prev,null);
+ if(state.arrayInfo==null)state.arrayInfo=new Stack<ArrayState>();
+ state.arrayInfo.push(new ArrayState());
+ }
+ // @Override
+ public boolean eval(Parsed<State> parsed, DerTag derTag) throws ParseException {
+ if(ji.name.equals(derTag.name) && !derTag.isEndTag) {
+ if(ji.isObject()) {
+ if(derTag.isEndTag) {
+ throw new ParseException("Unexpected End Tag </" + derTag.name + '>');
+ } else {
+ ArrayState ai = parsed.state.arrayInfo.peek();
+ if(ai.firstObj || ai.didNext) {
+ ai.firstObj = false;
+ ai.didNext = false;
+ parsed.event = START_OBJ;
+ parsed.name=derTag.name;
+ parsed.state.greatExp = new ObjectExpectations(parsed.state,ji,this,true, derTag);
+ } else {
+ ai.didNext = true;
+ parsed.event = NEXT;
+ parsed.state.unevaluated = derTag;
+ }
+ }
+ } else { // a leave
+ if(derTag.isEndTag) {
+ throw new ParseException("Misplaced End Tag </" + parsed.name + '>');
+ } else {
+ parsed.state.greatExp = new LeafExpectations(parsed.state, ji, this);
+ return true; // finish out Leaf without returning
+ }
+ }
+ } else { // Tag now different... Array is done
+ parsed.state.unevaluated = derTag;
+ parsed.event=END_ARRAY;
+ parsed.state.greatExp = prev;
+ parsed.state.arrayInfo.pop();
+ }
+ return false;
+ }
+ }
+ // @Override
+ public Parsed<State> newParsed() throws ParseException {
+ return new Parsed<State>(new State(jaxInfo, null));
+ }
+
+ // @Override
+ public TimeTaken start(Env env) {
+ return env.start("Rosetta XML In", Env.XML);
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxEval.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxEval.java
new file mode 100644
index 0000000..2708aa2
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxEval.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+public interface JaxEval{
+ public abstract JaxEval eval(Parsed<?> p) throws ParseException;
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxInfo.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxInfo.java
new file mode 100644
index 0000000..5f38c8c
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxInfo.java
@@ -0,0 +1,248 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public class JaxInfo {
+ private static final String DEFAULT = "##default";
+ public static final int DATA = 0;
+ public static final int ARRAY = 1;
+ public static final int OBJECT = 2;
+
+ public final String name;
+ public final Class<?> clss;
+ public Map<String, JaxInfo> extensions; // Classes, which might be found at runtime, that extend this class. Lazy Instantiation
+ public final JaxInfo[] members;
+ public final boolean isArray;
+ public final boolean isString;
+ public final boolean required;
+ public final boolean nillable;
+ public String ns;
+ public boolean isObject() {return members!=null;}
+
+ private JaxInfo(String n, String ns, Class<?> c, JaxInfo[] members, boolean string, boolean array, boolean required, boolean nillable) {
+ name = n;
+ this.ns = ns;
+ clss = c;
+ this.members = members;
+ this.isString = string;
+ isArray = array;
+ this.required = required;
+ this.nillable = nillable;
+ extensions = null;
+ }
+
+
+ public int getType() {
+ if(isArray)return ARRAY;
+ else if(members!=null)return OBJECT;
+ return DATA;
+ }
+
+ public JaxInfo getDerived(String derivedName) {
+ JaxInfo derived;
+ // Lazy Instantiation
+ if(extensions == null) {
+ extensions = new HashMap<String,JaxInfo>();
+ derived = null;
+ } else {
+ derived = extensions.get(derivedName);
+ }
+
+ if(derived == null) {
+ //TODO for the moment, Classes are in same package
+ Package pkg = clss.getPackage();
+ try {
+ Class<?> dc = getClass().getClassLoader().loadClass(pkg.getName()+'.'+Character.toUpperCase(derivedName.charAt(0))+derivedName.substring(1));
+ derived = JaxInfo.build(dc, this); // Use this JAXInfo's name so the tags are correct
+ extensions.put(derivedName, derived);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return derived;
+ }
+
+ public static JaxInfo get(JaxInfo[] fields, String name) {
+ for(JaxInfo f : fields) {
+ if(name.equals(f.name)) return f;
+ }
+ return null;
+ }
+
+ /**
+ * Build up JAXB Information (recursively)
+ *
+ * @param cls
+ * @param rootNns
+ * @return
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws ClassNotFoundException
+ * @throws ParseException
+ */
+ public static JaxInfo build(Class<?> cls, JaxInfo parent) throws NoSuchFieldException, ClassNotFoundException, ParseException {
+ return new JaxInfo(parent.name,parent.ns, cls,buildFields(cls,parent.ns),parent.isString, parent.isArray,parent.required,parent.nillable);
+ }
+ /**
+ * Build up JAXB Information (recursively)
+ *
+ * @param cls
+ * @param rootNns
+ * @return
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws ClassNotFoundException
+ * @throws ParseException
+ */
+ public static JaxInfo build(Class<?> cls, String ... rootNns) throws SecurityException, NoSuchFieldException, ClassNotFoundException, ParseException {
+ String defaultNS;
+ if(rootNns.length>0 && rootNns[0]!=null) {
+ defaultNS = rootNns[0];
+ } else {
+ Package pkg = cls.getPackage();
+ XmlSchema xs = pkg.getAnnotation(XmlSchema.class);
+ defaultNS = xs==null?"":xs.namespace();
+ }
+ String name;
+ if(rootNns.length>1) {
+ name = rootNns[1];
+ } else {
+ XmlRootElement xre = cls.getAnnotation(XmlRootElement.class);
+ if(xre!=null) {
+ name = xre.name();
+ } else {
+ XmlType xt = cls.getAnnotation(XmlType.class);
+ if(xt!=null) {
+ name=xt.name();
+ } else {
+ throw new ParseException("Need a JAXB Object with XmlRootElement, or stipulate in parms");
+ }
+ }
+ }
+
+ return new JaxInfo(name,defaultNS, cls,buildFields(cls,defaultNS),false,false,false,false);
+ }
+
+ // Build up the name and members of this particular class
+ // This is recursive, if a member is a JAXB Object as well.
+ private static JaxInfo[] buildFields(Class<?> clazz, String defaultNS) throws SecurityException, NoSuchFieldException, ClassNotFoundException {
+ ArrayList<JaxInfo> fields = null; // allow for lazy instantiation, because many structures won't have XmlType
+ Class<?> cls = clazz;
+ // Build up Method names from JAXB Annotations
+ XmlType xt;
+ while((xt = cls.getAnnotation(XmlType.class))!=null) {
+ if(fields==null)fields = new ArrayList<JaxInfo>();
+ for(String field : xt.propOrder()) {
+ if("".equals(field)) break; // odd bug. "" returned when no fields exist, rather than empty array
+ Field rf = cls.getDeclaredField(field);
+ Class<?> ft = rf.getType();
+
+ boolean required = false;
+ boolean nillable = false;
+ String xmlName = field;
+ String namespace = defaultNS;
+
+ XmlElement xe = rf.getAnnotation(XmlElement.class);
+ if(xe!=null) {
+ xmlName=xe.name();
+ required = xe.required();
+ nillable = false;
+ if(DEFAULT.equals(xmlName)) {
+ xmlName = field;
+ }
+ namespace = xe.namespace();
+ if(DEFAULT.equals(namespace)) {
+ namespace = defaultNS;
+ }
+ }
+ // If object is a List, then it is possible multiple, per XML/JAXB evaluation
+ if(ft.isAssignableFrom(List.class)) {
+ Type t = rf.getGenericType();
+ String classname = t.toString();
+ int start = classname.indexOf('<');
+ int end = classname.indexOf('>');
+ Class<?> genClass = Class.forName(classname.substring(start+1, end));
+ xe = genClass.getAnnotation(XmlElement.class);
+ if(xe!=null && !DEFAULT.equals(xe.namespace())) {
+ namespace = xe.namespace();
+ }
+ // add recursed recursed member, marked as array
+ fields.add(new JaxInfo(xmlName,namespace,genClass,buildFields(genClass,namespace), genClass.equals(String.class),true,required,nillable));
+ } else {
+ boolean isString = ft.equals(String.class) || ft.equals(XMLGregorianCalendar.class);
+ // add recursed member
+ fields.add(new JaxInfo(xmlName,namespace,ft,buildFields(ft,namespace),isString,false,required,nillable));
+ }
+ }
+ cls = cls.getSuperclass();
+ };
+ if(fields!=null) {
+ JaxInfo[] rv = new JaxInfo[fields.size()];
+ fields.toArray(rv);
+ return rv;
+ } else {
+ return null;
+ }
+ }
+
+
+ public StringBuilder dump(StringBuilder sb, int idx) {
+ for(int i=0;i<idx;++i)sb.append(' ');
+ sb.append("Field ");
+ sb.append(name);
+ sb.append(" [");
+ sb.append(clss.getName());
+ sb.append("] ");
+ if(isArray)sb.append(" (array)");
+ if(required)sb.append(" (required)");
+ if(nillable)sb.append(" (nillable)");
+ if(members!=null) {
+ for(JaxInfo f : members) {
+ sb.append('\n');
+ f.dump(sb,idx+2);
+ }
+ }
+ return sb;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Structure of ");
+ sb.append(clss.getName());
+ sb.append('\n');
+ dump(sb,2);
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxSet.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxSet.java
new file mode 100644
index 0000000..bb6784c
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/JaxSet.java
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * For specific XML class, quickly find a Setter Method which will load the object
+ *
+ * Object type of Setter must match String at this time.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public class JaxSet<T> {
+ private static Map<Class<?>,JaxSet<?>> jsets = new HashMap<Class<?>,JaxSet<?>>();
+ private Map<String,Setter<T>> members;
+
+ private JaxSet(Class<?> cls) {
+ members = new TreeMap<String, Setter<T>>();
+ XmlType xmltype = cls.getAnnotation(XmlType.class);
+ Class<?> paramType[] = new Class[] {String.class};
+ for(String str : xmltype.propOrder()) {
+ try {
+ String setName = "set" + Character.toUpperCase(str.charAt(0)) + str.subSequence(1, str.length());
+ Method meth = cls.getMethod(setName,paramType );
+ if(meth!=null) {
+ members.put(str, new Setter<T>(meth) {
+ public void set(T o, Object t) throws ParseException {
+ try {
+ this.meth.invoke(o, t);
+ } catch (Exception e) {
+ throw new ParseException(e);
+ }
+ }
+ });
+ }
+ } catch (Exception e) {
+ // oops
+ }
+ }
+ }
+
+ public static abstract class Setter<O> {
+ protected final Method meth;
+ public Setter(Method meth) {
+ this.meth = meth;
+ }
+ public abstract void set(O o, Object obj) throws ParseException;
+ }
+
+ public static <X> JaxSet<X> get(Class<?> cls) {
+ synchronized(jsets) {
+ @SuppressWarnings("unchecked")
+ JaxSet<X> js = (JaxSet<X>)jsets.get(cls);
+ if(js == null) {
+ jsets.put(cls, js = new JaxSet<X>(cls));
+ }
+ return js;
+ }
+ }
+
+ public Setter<T> get(String key) {
+ return members.get(key);
+ }
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Ladder.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Ladder.java
new file mode 100644
index 0000000..51cec07
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Ladder.java
@@ -0,0 +1,113 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+
+/**
+ * A Ladder is a Stack like Storage Class, but where you can ascend and descend while
+ * the elements exists.
+ *
+ * Like an extension ladder, you can make taller as you go
+ *
+ * @author Jonathan
+ *
+ */
+public class Ladder<T> {
+ public static final int DEFAULT_INIT_SIZE=8;
+ private final int init_size;
+ private int rung; // as in ladder
+ private Object[] struts;
+
+ public Ladder() {
+ rung=0;
+ init_size = DEFAULT_INIT_SIZE;
+ struts=new Object[init_size];
+ }
+
+ public Ladder(int initSize) {
+ rung=0;
+ init_size = initSize;
+ struts=new Object[init_size];
+ }
+
+ public void bottom() {
+ rung = 0;
+ }
+
+ public void top() {
+ rung = struts.length-1;
+ while(rung>0 && struts[rung]==null)--rung;
+ }
+
+ public int howHigh() {
+ return rung;
+ }
+
+ public void jumpTo(int rung) {
+ if(rung>=struts.length) {
+ Object[] temp = new Object[init_size*((rung/init_size)+1)];
+ System.arraycopy(struts, 0, temp, 0, struts.length);
+ struts = temp;
+ }
+ this.rung = rung;
+ }
+
+ public int height() {
+ return struts.length;
+ }
+
+ public void cutTo(int rungs) {
+ Object[] temp = new Object[rungs];
+ System.arraycopy(struts, 0, temp, 0, Math.min(rungs, struts.length));
+ struts = temp;
+ }
+
+ public void ascend() {
+ ++rung;
+ if(rung>=struts.length) {
+ Object[] temp = new Object[struts.length+init_size];
+ System.arraycopy(struts, 0, temp, 0, struts.length);
+ struts = temp;
+ }
+ }
+
+ public void descend() {
+ --rung;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T peek() {
+ return (T)struts[rung];
+ }
+
+ public void push(T t) {
+ struts[rung]=t;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T pop() {
+ T t = (T)struts[rung];
+ struts[rung]=null;
+ return t;
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Marshal.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Marshal.java
new file mode 100644
index 0000000..d482b24
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Marshal.java
@@ -0,0 +1,81 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.util.Iterator;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+
+public abstract class Marshal<T> implements Parse<T, Marshal.State> {
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.rosetta.Parse#newParsed()
+ */
+ @Override
+ public Parsed<State> newParsed() throws ParseException {
+ return new Parsed<State>(new State());
+ }
+
+ @Override
+ public TimeTaken start(Env env) {
+ //TODO is a way to mark not-JSON?
+ return env.start("Rosetta Marshal", Env.JSON);
+ };
+
+ public static class State {
+ // Note: Need a STATEFUL stack... one that will remain stateful until marked as finished
+ // "finished" is know by Iterators with no more to do/null
+ // Thus the concept of "Ladder", which one ascends and decends
+ public Ladder<Iterator<?>> ladder = new Ladder<Iterator<?>>();
+ public boolean smallest = true;
+ }
+
+ public static final Iterator<Void> DONE_ITERATOR = new Iterator<Void>() {
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+
+ @Override
+ public Void next() {
+ return null;
+ }
+
+ @Override
+ public void remove() {
+ }
+ };
+
+ /**
+ * Typical definition of Done is when Iterator in Ladder is "DONE_ITERATOR"
+ *
+ * It is important, however, that the "Ladder Rung" is set to the right level.
+ *
+ * @param state
+ * @return
+ */
+ public boolean amFinished(State state) {
+ return DONE_ITERATOR.equals(state.ladder.peek());
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Nulls.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Nulls.java
new file mode 100644
index 0000000..38b021e
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Nulls.java
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+
+public class Nulls {
+ public static final Parse<Reader, ?> IN = new Parse<Reader, Void>() {
+
+ // @Override
+ public Parsed<Void> parse(Reader r, Parsed<Void> parsed)throws ParseException {
+ parsed.event = Parse.END_DOC;
+ return parsed;
+ }
+
+ // @Override
+ public Parsed<Void> newParsed() {
+ Parsed<Void> parsed = new Parsed<Void>();
+ parsed.event = Parse.END_DOC;
+ return parsed;
+ }
+
+ // @Override
+ public TimeTaken start(Env env) {
+ return env.start("IN", Env.SUB);
+ }
+
+ };
+
+ public static final Out OUT = new Out() {
+
+ // @Override
+ public <IN,S> void extract(IN in, Writer writer, Parse<IN, S> parse, boolean ... options)throws IOException, ParseException {
+ }
+ @Override
+ public String logName() {
+ return "Rosetta NULL";
+ }
+
+
+ };
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Out.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Out.java
new file mode 100644
index 0000000..567a626
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Out.java
@@ -0,0 +1,43 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public abstract class Out {
+ public abstract<IN,S> void extract(IN in, Writer writer, Parse<IN, S> parse, boolean ... options) throws IOException, ParseException;
+
+ public<IN,S> void extract(IN in, OutputStream os, Parse<IN, S> parse, boolean ... options) throws IOException, ParseException {
+ Writer w = new OutputStreamWriter(os);
+ try {
+ extract(in, w, parse, options);
+ } finally {
+ w.flush();
+ }
+ }
+
+ public abstract String logName();
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJax.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJax.java
new file mode 100644
index 0000000..db7b956
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJax.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class OutJax extends Out {
+ private JaxEval jaxEval;
+
+ public OutJax(JaxEval je) {
+ this.jaxEval = je;
+ }
+
+ @Override
+ public <IN,S> void extract(IN in, Writer writer, Parse<IN, S> parse, boolean... options) throws IOException, ParseException {
+ Parsed<S> p = parse.newParsed();
+ JaxEval je = this.jaxEval;
+ while((p = parse.parse(in,p.reuse())).valid()) {
+ if(je==null)throw new ParseException("Incomplete content");
+ je = je.eval(p);
+ }
+
+ }
+
+ @Override
+ public String logName() {
+ return "Rosetta JAX";
+ }
+
+
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java
new file mode 100644
index 0000000..2340bdb
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java
@@ -0,0 +1,232 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Stack;
+
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+
+public class OutJson extends Out {
+
+ @Override
+ public<IN,S> void extract(IN in, Writer writer, Parse<IN, S> prs, boolean ... options) throws IOException, ParseException {
+ Parsed<S> p = prs.newParsed();
+ IndentPrintWriter ipw;
+ if(options.length>0 && options[0]) { // is Pretty
+ ipw = writer instanceof IndentPrintWriter?(IndentPrintWriter)writer:new IndentPrintWriter(writer);
+ writer = ipw;
+ } else {
+ ipw = null;
+ }
+
+ // If it's a fragment, print first Object Name. If root Object, skip first name
+ Stack<LevelStack> jsonLevel = new Stack<LevelStack>();
+ jsonLevel.push(new LevelStack(options.length>1 && options[1]));
+ boolean print = true, hadData=false;
+ char afterName=0, beforeName=0, maybe = 0, prev=0;
+
+ int count = 0;
+ while((p = prs.parse(in,p.reuse())).valid()) {
+ ++count;
+ switch(p.event) {
+ case 1:
+ continue;
+ case 2:
+ if(count==2) { // it's empty, write open/close on it's own
+ writer.append('{');
+ writer.append('}');
+ }
+ writer.flush();
+ return;
+ case '{':
+ afterName = '{';
+ if(jsonLevel.peek().printObjectName) {
+ print = true;
+ } else { // don't print names on first
+ print=false;
+ }
+ maybe=jsonLevel.peek().listItem();
+ jsonLevel.push(new LevelStack(true));
+ break;
+ case '}':
+ if(p.hasData()) { // if we have data, we print that, so may need to prepend a comma.
+ maybe = jsonLevel.peek().listItem();
+ } else { // No data means just print,
+ p.name = ""; // XML tags come through with names, but no data
+ }
+ print = true;
+ jsonLevel.pop();
+ afterName = p.event;
+ break;
+ case '[':
+ afterName = p.event;
+ if((prev==',' && !hadData) || prev==']')maybe=',';
+ else maybe = jsonLevel.peek().listItem();
+
+ jsonLevel.push(new LevelStack(false));
+ print=true;
+ break;
+ case ']':
+ afterName = p.event;
+ if(p.hasData()) {
+ if(prev==',' && !hadData)maybe=',';
+ else maybe = jsonLevel.peek().listItem();
+ } else {
+ p.name = ""; // XML tags come through with names, but no data
+ }
+ jsonLevel.pop();
+
+ print = true;
+ break;
+ case 3:
+ case ',':
+ if(!p.hasData()) {
+ p.isString=false;
+ print=false;
+ } else {
+ maybe=jsonLevel.peek().listItem();
+ print = true;
+ }
+ break;
+ default:
+ print = true;
+ }
+
+ if(maybe!=0) {
+ if(ipw==null)writer.append(maybe);
+ else ipw.println(maybe);
+ maybe = 0;
+ }
+
+ if(beforeName!=0) {
+ if(ipw==null)writer.append(beforeName);
+ else ipw.println(beforeName);
+ beforeName = 0;
+ }
+ if(print) {
+ if(p.hasName()) {
+ writer.append('"');
+ if(p.event==3)writer.append("__");
+ writer.append(p.name);
+ writer.append("\":");
+ }
+ if(p.hasData()) {
+ if(p.isString) {
+ writer.append('"');
+ escapedWrite(writer, p.sb);
+ writer.append('"');
+ } else if(p.sb.length()>0) {
+ writer.append(p.sb);
+ }
+ }
+ }
+ if(afterName!=0) {
+ if(ipw==null)writer.append(afterName);
+ else {
+ switch(afterName) {
+ case '{':
+ ipw.println(afterName);
+ ipw.inc();
+ break;
+ case '}':
+ ipw.dec();
+ ipw.println();
+ ipw.print(afterName);
+ break;
+ case ']':
+ if(prev=='}' || prev==',')ipw.println();
+ ipw.dec();
+ ipw.print(afterName);
+ break;
+
+ case ',':
+ ipw.println(afterName);
+ break;
+ default:
+ ipw.print(afterName);
+ }
+ }
+ afterName = 0;
+ }
+
+ if(ipw!=null) {
+ switch(p.event) {
+ case '[':
+ ipw.inc();
+ ipw.println();
+ break;
+ }
+ }
+ prev = p.event;
+ hadData = p.hasData();
+
+ }
+ writer.flush();
+ }
+
+ private void escapedWrite(Writer writer, StringBuilder sb) throws IOException {
+ char c;
+ for(int i=0;i<sb.length();++i) {
+ switch(c=sb.charAt(i)) {
+ case '\\':
+ writer.append(c);
+ if(i<sb.length()) {
+ c=sb.charAt(++i);
+ writer.append(c);
+ }
+ break;
+ case '"':
+ writer.append('\\');
+ // Passthrough on purpose
+ default:
+ writer.append(c);
+ }
+ }
+
+
+ }
+
+ @Override
+ public String logName() {
+ return "Rosetta JSON";
+ }
+
+ private static class LevelStack {
+ public boolean printObjectName=false;
+ private boolean first_n_List=true;
+
+ public LevelStack(boolean printObjectName) {
+ this.printObjectName = printObjectName;
+ }
+
+ public char listItem() {
+ if(first_n_List) {
+ first_n_List=false;
+ return 0;
+ } else {
+ return ',';
+ }
+ }
+ }
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutRaw.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutRaw.java
new file mode 100644
index 0000000..bf833f7
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutRaw.java
@@ -0,0 +1,46 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class OutRaw extends Out{
+
+ @Override
+ public<IN,S> void extract(IN in, Writer writer, Parse<IN,S> prs, boolean ... options) throws IOException, ParseException {
+ Parsed<S> p = prs.newParsed();
+
+ while((p = prs.parse(in,p.reuse())).valid()) {
+ writer.append(p.toString());
+ writer.append('\n');
+ }
+ }
+
+ @Override
+ public String logName() {
+ return "Rosetta RAW";
+ }
+
+
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutXML.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutXML.java
new file mode 100644
index 0000000..f3ce1c2
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutXML.java
@@ -0,0 +1,225 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+
+public class OutXML extends Out{
+ private static final String XMLNS_XSI = "xmlns:xsi";
+ public static final String XML_INFO = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
+ public static final String XML_SCHEMA_INSTANCE = "http://www.w3.org/2001/XMLSchema-instance";
+
+ private String root;
+ private List<Prop> props;
+
+ public OutXML(String root, String ... params) {
+ this.root = root;
+ props = new ArrayList<Prop>();
+ for(String p : params) {
+ String[] tv=p.split("=");
+ if(tv.length==2)
+ props.add(new Prop(tv[0],tv[1]));
+ }
+ }
+
+ public OutXML(JaxInfo jaxInfo) {
+ this(jaxInfo.name,genNS(jaxInfo));
+ }
+
+ public OutXML(InXML inXML) {
+ this(inXML.jaxInfo.name,genNS(inXML.jaxInfo));
+ }
+
+ private static String[] genNS(JaxInfo jaxInfo) {
+ return new String[] {"xmlns=" + jaxInfo.ns};
+ }
+
+
+ @Override
+ public<IN,S> void extract(IN in, Writer writer, Parse<IN,S> prs, boolean ... options) throws IOException, ParseException {
+ Parsed<S> p = prs.newParsed();
+ Stack<Level> stack = new Stack<Level>();
+ // If it's an IndentPrintWriter, it is pretty printing.
+ boolean pretty = (options.length>0&&options[0]);
+
+ IndentPrintWriter ipw;
+ if(pretty) {
+ if(writer instanceof IndentPrintWriter) {
+ ipw = (IndentPrintWriter)writer;
+ } else {
+ writer = ipw = new IndentPrintWriter(writer);
+ }
+ } else {
+ ipw=null;
+ }
+ boolean closeTag = false;
+ Level level = new Level(null);
+ while((p = prs.parse(in,p.reuse())).valid()) {
+ if(!p.hasName() && level.multi!=null) {
+ p.name=level.multi;
+ }
+ if(closeTag && p.event!=Parse.ATTRIB) {
+ writer.append('>');
+ if(pretty)writer.append('\n');
+ closeTag = false;
+ }
+ switch(p.event) {
+ case Parse.START_DOC:
+ if(!(options.length>1&&options[1])) // if not a fragment, print XML Info data
+ if(pretty)ipw.println(XML_INFO);
+ else writer.append(XML_INFO);
+ break;
+ case Parse.END_DOC:
+ break;
+ case Parse.START_OBJ:
+ stack.push(level);
+ level = new Level(level);
+ if(p.hasName()) {
+ closeTag = tag(writer,level.sbw,pretty,pretty,p.name,null);
+ } else if(root!=null && stack.size()==1) { // first Object
+ closeTag = tag(writer,level.sbw,pretty,pretty,root,null);
+ // Write Root Props
+ for(Prop prop : props) {
+ attrib(writer,pretty,prop.tag, prop.value,level);
+ }
+ }
+ if(pretty)ipw.inc();
+ break;
+ case Parse.END_OBJ:
+ if(p.hasData())
+ closeTag = tag(writer,writer,pretty,false,p.name, XmlEscape.convert(p.sb));
+ if(pretty)ipw.dec();
+ writer.append(level.sbw.getBuffer());
+ level = stack.pop();
+ break;
+ case Parse.START_ARRAY:
+ level.multi = p.name;
+ break;
+ case Parse.END_ARRAY:
+ if(p.hasData())
+ closeTag = tag(writer,writer,pretty,false, p.name, XmlEscape.convert(p.sb));
+ level.multi=null;
+ break;
+ case Parse.ATTRIB:
+ if(p.hasData())
+ attrib(writer,pretty,p.name, XmlEscape.convert(p.sb), level);
+ break;
+ case Parse.NEXT:
+ if(p.hasData())
+ closeTag = tag(writer,writer,pretty, false,p.name, XmlEscape.convert(p.sb));
+ break;
+ }
+ }
+ writer.append(level.sbw.getBuffer());
+ writer.flush();
+ }
+
+ private class Level {
+ public final StringBuilderWriter sbw;
+ public String multi;
+ private Level prev;
+ private Map<String,String> nses;
+
+ public Level(Level level) {
+ sbw = new StringBuilderWriter();
+ multi = null;
+ prev = level;
+ }
+
+ public boolean hasPrinted(String ns, String value, boolean create) {
+ boolean rv = false;
+ if(nses==null) {
+ if(prev!=null)rv = prev.hasPrinted(ns, value, false);
+ } else {
+ String v = nses.get(ns);
+ return value.equals(v); // note: accomodates not finding NS as well
+ }
+
+ if(create && !rv) {
+ if(nses == null) nses = new HashMap<String,String>();
+ nses.put(ns, value);
+ }
+ return rv;
+ }
+
+
+
+ }
+
+ private boolean tag(Writer fore, Writer aft, boolean pretty, boolean returns, String tag, String data) throws IOException {
+ fore.append('<');
+ fore.append(tag);
+ if(data!=null) {
+ fore.append('>'); // if no data, it may need some attributes...
+ fore.append(data);
+ if(returns)fore.append('\n');
+ }
+ aft.append("</");
+ aft.append(tag);
+ aft.append(">");
+ if(pretty)aft.append('\n');
+ return data==null;
+ }
+
+ private void attrib(Writer fore, boolean pretty, String tag, String value, Level level) throws IOException {
+ String realTag = tag.startsWith("__")?tag.substring(2):tag; // remove __
+ if(realTag.equals(Parsed.EXTENSION_TAG)) { // Convert Derived name into XML defined Inheritance
+ fore.append(" xsi:type=\"");
+ fore.append(value);
+ fore.append('"');
+ if(!level.hasPrinted(XMLNS_XSI, XML_SCHEMA_INSTANCE,true)) {
+ fore.append(' ');
+ fore.append(XMLNS_XSI);
+ fore.append("=\"");
+ fore.append(XML_SCHEMA_INSTANCE);
+ fore.append("\"");
+ }
+ } else {
+ if(realTag.startsWith("xmlns:") ) {
+ if(level.hasPrinted(realTag, value, true)) {
+ return;
+ }
+ }
+ fore.append(' ');
+ fore.append(realTag);
+ fore.append("=\"");
+ fore.append(value);
+ fore.append('"');
+ }
+ }
+
+ @Override
+ public String logName() {
+ return "Rosetta XML";
+ }
+
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parse.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parse.java
new file mode 100644
index 0000000..657baf5
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parse.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+
+public interface Parse<IN, S> {
+ public Parsed<S> parse(IN in, Parsed<S> parsed) throws ParseException;
+
+ // EVENTS
+ public static final char NONE = 0;
+ public static final char START_DOC = 1;
+ public static final char END_DOC = 2;
+ public static final char ATTRIB = 3;
+
+ public static final char NEXT = ',';
+ public static final char START_OBJ = '{';
+ public static final char END_OBJ = '}';
+ public static final char START_ARRAY = '[';
+ public static final char END_ARRAY = ']';
+
+ public Parsed<S> newParsed() throws ParseException;
+ public TimeTaken start(Env env);
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/ParseException.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/ParseException.java
new file mode 100644
index 0000000..d986776
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/ParseException.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+public class ParseException extends Exception {
+ private static final long serialVersionUID = 7808836939102997012L;
+
+ public ParseException() {
+ }
+
+ public ParseException(String message) {
+ super(message);
+ }
+
+ public ParseException(Throwable cause) {
+ super(cause);
+ }
+
+ public ParseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parsed.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parsed.java
new file mode 100644
index 0000000..326c5bb
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Parsed.java
@@ -0,0 +1,89 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+
+public class Parsed<S> {
+ public static final String EXTENSION_TAG="extension";
+
+ public boolean isString;
+
+ public StringBuilder sb;
+ public char event;
+ public String name;
+ public S state;
+
+ public Parsed() {
+ this(null);
+ }
+
+ // Package on purpose
+ Parsed(S theState) {
+ sb = new StringBuilder();
+ isString = false;
+ event = Parse.NONE;
+ name = "";
+ state = theState;
+ }
+
+ public boolean valid() {
+ return event!=Parse.NONE;
+ }
+
+ public Parsed<S> reuse() {
+ isString=false;
+ sb.setLength(0);
+ event = Parse.NONE;
+ name = "";
+ // don't touch T...
+ return this;
+ }
+
+ public void dataIsName() {
+ name = sb.toString();
+ sb.setLength(0);
+ }
+
+ public boolean hasName() {
+ return name.length()>0;
+ }
+
+ public boolean hasData() {
+ return sb.length()>0;
+ }
+
+ public String toString() {
+ StringBuilder sb2 = new StringBuilder();
+ if(event<40)sb2.append((int)event);
+ else sb2.append(event);
+ sb2.append(" - ");
+ sb2.append(name);
+ if(sb.length()>0) {
+ sb2.append(" : ");
+ if(isString)sb2.append('"');
+ sb2.append(sb);
+ if(isString)sb2.append('"');
+ }
+ return sb2.toString();
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Prop.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Prop.java
new file mode 100644
index 0000000..07bd40f
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Prop.java
@@ -0,0 +1,43 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+class Prop {
+ public String tag;
+ public String value;
+ public Prop(String t, String v) {
+ tag = t;
+ value =v;
+ }
+
+ public Prop(String t_equals_v) {
+ String[] tv = t_equals_v.split("=");
+ if(tv.length>1) {
+ tag = tv[0];
+ value = tv[1];
+ }
+ }
+
+ public String toString() {
+ return tag + '=' + value;
+ }
+}
\ No newline at end of file
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Saved.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Saved.java
new file mode 100644
index 0000000..45c2705
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/Saved.java
@@ -0,0 +1,194 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.List;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.rosetta.Saved.State;
+
+/**
+ * An Out Object that will save off produced Parsed Stream and
+ * a Parse (In) Object that will reproduce Parsed Stream on demand
+ *
+ * @author Jonathan
+ *
+ */
+public class Saved extends Out implements Parse<Reader, State>{
+ private static final String ROSETTA_SAVED = "Rosetta Saved";
+ private final static int INIT_SIZE=128;
+ private Content content[];
+ private int idx;
+ private boolean append = false;
+
+ /**
+ * Read from Parsed Stream and save
+ */
+ // @Override
+ public<IN,S> void extract(IN in, Writer ignore, Parse<IN,S> parser, boolean ... options) throws IOException, ParseException {
+ Parsed<S> p = parser.newParsed();
+ if(!append) {
+ // reuse array if not too big
+ if(content==null||content.length>INIT_SIZE*3) {
+ content = new Content[INIT_SIZE];
+ idx = -1;
+ } else do {
+ content[idx]=null;
+ } while(--idx>=0);
+ }
+
+ // Note: idx needs to be -1 on initialization and no appendages
+ while((p = parser.parse(in,p.reuse())).valid()) {
+ if(!(append && (p.event==START_DOC || p.event==END_DOC))) { // skip any start/end of document in appendages
+ if(++idx>=content.length) {
+ Content temp[] = new Content[content.length*2];
+ System.arraycopy(content, 0, temp, 0, idx);
+ content = temp;
+ }
+ content[idx]= new Content(p);
+ }
+ }
+ }
+
+ // @Override
+ public Parsed<State> parse(Reader ignore, Parsed<State> parsed) throws ParseException {
+ int i;
+ if((i=parsed.state.count++)<=idx)
+ content[i].load(parsed);
+ else
+ parsed.event = Parse.NONE;
+ return parsed;
+ }
+
+ public Content[] cut(char event, int count) {
+ append = true;
+ for(int i=idx;i>=0;--i) {
+ if(content[i].event==event) count--;
+ if(count==0) {
+ Content[] appended = new Content[idx-i+1];
+ System.arraycopy(content, i, appended, 0, appended.length);
+ idx = i-1;
+ return appended;
+ }
+ }
+ return new Content[0];
+ }
+
+ public void paste(Content[] appended) {
+ if(appended!=null) {
+ if(idx+appended.length>content.length) {
+ Content temp[] = new Content[content.length*2];
+ System.arraycopy(content, 0, temp, 0, idx);
+ content = temp;
+ }
+ System.arraycopy(appended,0,content,idx+1,appended.length);
+ idx+=appended.length;
+ }
+ this.append = false;
+ }
+
+ public static class State {
+ public int count = 0;
+ }
+
+ public static class Content {
+ private boolean isString;
+ private char event;
+ private String name;
+ private List<Prop> props;
+ private String str;
+
+ public Content(Parsed<?> p) {
+ isString = p.isString;
+ event = p.event;
+ name = p.name;
+ // avoid copying, because most elements don't have content
+ // Cannot set to "equals", because sb ends up being cleared (and reused)
+ str = p.sb.length()==0?null:p.sb.toString();
+ }
+
+ public void load(Parsed<State> p) {
+ p.isString = isString;
+ p.event = event;
+ p.name = name;
+ if(str!=null)
+ p.sb.append(str);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(event);
+ sb.append(" - ");
+ sb.append(name);
+ sb.append(": ");
+ if(isString)sb.append('"');
+ sb.append(str);
+ if(isString)sb.append('"');
+ sb.append(' ');
+ if(props!=null) {
+ boolean comma = false;
+ for(Prop prop : props) {
+ if(comma)sb.append(',');
+ else comma = true;
+ sb.append(prop.tag);
+ sb.append('=');
+ sb.append(prop.value);
+ }
+ }
+ return sb.toString();
+ }
+ }
+
+ //// @Override
+ public Parsed<State> newParsed() {
+ Parsed<State> ps = new Parsed<State>(new State());
+ return ps;
+ }
+
+ /**
+ * Convenience function
+ * @param rdr
+ * @param in
+ * @throws IOException
+ * @throws ParseException
+ */
+ public<IN,S> void load(IN in, Parse<IN, S> parser) throws IOException, ParseException {
+ extract(in,(Writer)null, parser);
+ }
+
+
+ // @Override
+ public TimeTaken start(Env env) {
+ return env.start(ROSETTA_SAVED, 0);
+ }
+
+ @Override
+ public String logName() {
+ return ROSETTA_SAVED;
+ }
+
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/XmlEscape.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/XmlEscape.java
new file mode 100644
index 0000000..f1cde6e
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/XmlEscape.java
@@ -0,0 +1,371 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+public class XmlEscape {
+ private XmlEscape() {}
+
+ private static final TreeMap<String,Integer> charMap; // see initialization at end
+ private static final TreeMap<Integer,String> intMap; // see initialization at end
+
+ public static void xmlEscape(StringBuilder sb, Reader r) throws ParseException {
+ try {
+ int c;
+ StringBuilder esc = new StringBuilder();
+ for(int cnt = 0;cnt<9 /*max*/; ++cnt) {
+ if((c=r.read())<0)throw new ParseException("Invalid Data: Unfinished Escape Sequence");
+ if(c!=';') {
+ esc.append((char)c);
+ } else { // evaluate
+ Integer i = charMap.get(esc.toString());
+ if(i==null) {
+ // leave in nasty XML format for now.
+ sb.append('&');
+ sb.append(esc);
+ sb.append(';');
+ } else {
+ sb.append((char)i.intValue());
+ }
+ break;
+ }
+ }
+
+
+ } catch (IOException e) {
+ throw new ParseException(e);
+ }
+ }
+
+ public static void xmlEscape(StringBuilder sb, int chr) {
+ sb.append('&');
+ sb.append(intMap.get(chr));
+ sb.append(';');
+ }
+
+ public static String convert(StringBuilder insb) {
+ int idx, ch;
+ StringBuilder sb=null;
+ for(idx=0;idx<insb.length();++idx) {
+ ch = insb.charAt(idx);
+ if(ch>=160 || ch==34 || ch==38 || ch==39 || ch==60 || ch==62) {
+ sb = new StringBuilder();
+ sb.append(insb,0,idx);
+ break;
+ }
+ }
+
+ if(sb==null)return insb.toString();
+
+ for(int i=idx;i<insb.length();++i) {
+ ch = insb.charAt(i);
+ if(ch<160) {
+ switch(ch) {
+ case 34: sb.append("""); break;
+ case 38: sb.append("&"); break;
+ case 39: sb.append("'"); break;
+ case 60: sb.append("<"); break;
+ case 62: sb.append(">"); break;
+ default:
+ sb.append((char)ch);
+ }
+ } else { // use map
+ String s = intMap.get(ch);
+ if(s==null)sb.append((char)ch);
+ else {
+ sb.append('&');
+ sb.append(s);
+ sb.append(';');
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ static {
+ charMap = new TreeMap<String, Integer>();
+ intMap = new TreeMap<Integer,String>();
+ charMap.put("quot", 34);
+ charMap.put("amp",38);
+ charMap.put("apos",39);
+ charMap.put("lt",60);
+ charMap.put("gt",62);
+ charMap.put("nbsp",160);
+ charMap.put("iexcl",161);
+ charMap.put("cent",162);
+ charMap.put("pound",163);
+ charMap.put("curren",164);
+ charMap.put("yen",165);
+ charMap.put("brvbar",166);
+ charMap.put("sect",167);
+ charMap.put("uml",168);
+ charMap.put("copy",169);
+ charMap.put("ordf",170);
+ charMap.put("laquo",171);
+ charMap.put("not",172);
+ charMap.put("shy",173);
+ charMap.put("reg",174);
+ charMap.put("macr",175);
+ charMap.put("deg",176);
+ charMap.put("plusmn",177);
+ charMap.put("sup2",178);
+ charMap.put("sup3",179);
+ charMap.put("acute",180);
+ charMap.put("micro",181);
+ charMap.put("para",182);
+ charMap.put("middot",183);
+ charMap.put("cedil",184);
+ charMap.put("sup1",185);
+ charMap.put("ordm",186);
+ charMap.put("raquo",187);
+ charMap.put("frac14",188);
+ charMap.put("frac12",189);
+ charMap.put("frac34",190);
+ charMap.put("iquest",191);
+ charMap.put("Agrave",192);
+ charMap.put("Aacute",193);
+ charMap.put("Acirc",194);
+ charMap.put("Atilde",195);
+ charMap.put("Auml",196);
+ charMap.put("Aring",197);
+ charMap.put("AElig",198);
+ charMap.put("Ccedil",199);
+ charMap.put("Egrave",200);
+ charMap.put("Eacute",201);
+ charMap.put("Ecirc",202);
+ charMap.put("Euml",203);
+ charMap.put("Igrave",204);
+ charMap.put("Iacute",205);
+ charMap.put("Icirc",206);
+ charMap.put("Iuml",207);
+ charMap.put("ETH",208);
+ charMap.put("Ntilde",209);
+ charMap.put("Ograve",210);
+ charMap.put("Oacute",211);
+ charMap.put("Ocirc",212);
+ charMap.put("Otilde",213);
+ charMap.put("Ouml",214);
+ charMap.put("times",215);
+ charMap.put("Oslash",216);
+ charMap.put("Ugrave",217);
+ charMap.put("Uacute",218);
+ charMap.put("Ucirc",219);
+ charMap.put("Uuml",220);
+ charMap.put("Yacute",221);
+ charMap.put("THORN",222);
+ charMap.put("szlig",223);
+ charMap.put("agrave",224);
+ charMap.put("aacute",225);
+ charMap.put("acirc",226);
+ charMap.put("atilde",227);
+ charMap.put("auml",228);
+ charMap.put("aring",229);
+ charMap.put("aelig",230);
+ charMap.put("ccedil",231);
+ charMap.put("egrave",232);
+ charMap.put("eacute",233);
+ charMap.put("ecirc",234);
+ charMap.put("euml",235);
+ charMap.put("igrave",236);
+ charMap.put("iacute",237);
+ charMap.put("icirc",238);
+ charMap.put("iuml",239);
+ charMap.put("eth",240);
+ charMap.put("ntilde",241);
+ charMap.put("ograve",242);
+ charMap.put("oacute",243);
+ charMap.put("ocirc",244);
+ charMap.put("otilde",245);
+ charMap.put("ouml",246);
+ charMap.put("divide",247);
+ charMap.put("oslash",248);
+ charMap.put("ugrave",249);
+ charMap.put("uacute",250);
+ charMap.put("ucirc",251);
+ charMap.put("uuml",252);
+ charMap.put("yacute",253);
+ charMap.put("thorn",254);
+ charMap.put("yuml",255);
+ charMap.put("OElig",338);
+ charMap.put("oelig",339);
+ charMap.put("Scaron",352);
+ charMap.put("scaron",353);
+ charMap.put("Yuml",376);
+ charMap.put("fnof",402);
+ charMap.put("circ",710);
+ charMap.put("tilde",732);
+ charMap.put("Alpha",913);
+ charMap.put("Beta",914);
+ charMap.put("Gamma",915);
+ charMap.put("Delta",916);
+ charMap.put("Epsilon",917);
+ charMap.put("Zeta",918);
+ charMap.put("Eta",919);
+ charMap.put("Theta",920);
+ charMap.put("Iota",921);
+ charMap.put("Kappa",922);
+ charMap.put("Lambda",923);
+ charMap.put("Mu",924);
+ charMap.put("Nu",925);
+ charMap.put("Xi",926);
+ charMap.put("Omicron",927);
+ charMap.put("Pi",928);
+ charMap.put("Rho",929);
+ charMap.put("Sigma",931);
+ charMap.put("Tau",932);
+ charMap.put("Upsilon",933);
+ charMap.put("Phi",934);
+ charMap.put("Chi",935);
+ charMap.put("Psi",936);
+ charMap.put("Omega",937);
+ charMap.put("alpha",945);
+ charMap.put("beta",946);
+ charMap.put("gamma",947);
+ charMap.put("delta",948);
+ charMap.put("epsilon",949);
+ charMap.put("zeta",950);
+ charMap.put("eta",951);
+ charMap.put("theta",952);
+ charMap.put("iota",953);
+ charMap.put("kappa",954);
+ charMap.put("lambda",955);
+ charMap.put("mu",956);
+ charMap.put("nu",957);
+ charMap.put("xi",958);
+ charMap.put("omicron",959);
+ charMap.put("pi",960);
+ charMap.put("rho",961);
+ charMap.put("sigmaf",962);
+ charMap.put("sigma",963);
+ charMap.put("tau",964);
+ charMap.put("upsilon",965);
+ charMap.put("phi",966);
+ charMap.put("chi",967);
+ charMap.put("psi",968);
+ charMap.put("omega",969);
+ charMap.put("thetasym",977);
+ charMap.put("upsih",978);
+ charMap.put("piv",982);
+ charMap.put("ensp",8194);
+ charMap.put("emsp",8195);
+ charMap.put("thinsp",8201);
+ charMap.put("zwnj",8204);
+ charMap.put("zwj",8205);
+ charMap.put("lrm",8206);
+ charMap.put("rlm",8207);
+ charMap.put("ndash",8211);
+ charMap.put("mdash",8212);
+ charMap.put("lsquo",8216);
+ charMap.put("rsquo",8217);
+ charMap.put("sbquo",8218);
+ charMap.put("ldquo",8220);
+ charMap.put("rdquo",8221);
+ charMap.put("bdquo",8222);
+ charMap.put("dagger",8224);
+ charMap.put("Dagger",8225);
+ charMap.put("bull",8226);
+ charMap.put("hellip",8230);
+ charMap.put("permil",8240);
+ charMap.put("prime",8242);
+ charMap.put("Prime",8243);
+ charMap.put("lsaquo",8249);
+ charMap.put("rsaquo",8250);
+ charMap.put("oline",8254);
+ charMap.put("frasl",8260);
+ charMap.put("euro",8364);
+ charMap.put("image",8465);
+ charMap.put("weierp",8472);
+ charMap.put("real",8476);
+ charMap.put("trade",8482);
+ charMap.put("alefsym",8501);
+ charMap.put("larr",8592);
+ charMap.put("uarr",8593);
+ charMap.put("rarr",8594);
+ charMap.put("darr",8595);
+ charMap.put("harr",8596);
+ charMap.put("crarr",8629);
+ charMap.put("lArr",8656);
+ charMap.put("uArr",8657);
+ charMap.put("rArr",8658);
+ charMap.put("dArr",8659);
+ charMap.put("hArr",8660);
+ charMap.put("forall",8704);
+ charMap.put("part",8706);
+ charMap.put("exist",8707);
+ charMap.put("empty",8709);
+ charMap.put("nabla",8711);
+ charMap.put("isin",8712);
+ charMap.put("notin",8713);
+ charMap.put("ni",8715);
+ charMap.put("prod",8719);
+ charMap.put("sum",8721);
+ charMap.put("minus",8722);
+ charMap.put("lowast",8727);
+ charMap.put("radic",8730);
+ charMap.put("prop",8733);
+ charMap.put("infin",8734);
+ charMap.put("ang",8736);
+ charMap.put("and",8743);
+ charMap.put("or",8744);
+ charMap.put("cap",8745);
+ charMap.put("cup",8746);
+ charMap.put("int",8747);
+ charMap.put("there4",8756);
+ charMap.put("sim",8764);
+ charMap.put("cong",8773);
+ charMap.put("asymp",8776);
+ charMap.put("ne",8800);
+ charMap.put("equiv",8801);
+ charMap.put("le",8804);
+ charMap.put("ge",8805);
+ charMap.put("sub",8834);
+ charMap.put("sup",8835);
+ charMap.put("nsub",8836);
+ charMap.put("sube",8838);
+ charMap.put("supe",8839);
+ charMap.put("oplus",8853);
+ charMap.put("otimes",8855);
+ charMap.put("perp",8869);
+ charMap.put("sdot",8901);
+ charMap.put("lceil",8968);
+ charMap.put("rceil",8969);
+ charMap.put("lfloor",8970);
+ charMap.put("rfloor",8971);
+ charMap.put("lang",9001);
+ charMap.put("rang",9002);
+ charMap.put("loz",9674);
+ charMap.put("spades",9824);
+ charMap.put("clubs",9827);
+ charMap.put("hearts",9829);
+ charMap.put("diams",9830);
+
+ for( Entry<String, Integer> es: charMap.entrySet()) {
+ if(es.getValue()>=160); // save small space... note that no longer has amp, etc.
+ intMap.put(es.getValue(), es.getKey());
+ }
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaDF.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaDF.java
new file mode 100644
index 0000000..68baebb
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaDF.java
@@ -0,0 +1,265 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.env;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.BaseDataFactory;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.DataFactory;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Data.TYPE;
+import org.onap.aaf.misc.env.jaxb.JAXBmar;
+import org.onap.aaf.misc.env.jaxb.JAXBumar;
+import org.onap.aaf.misc.rosetta.InJson;
+import org.onap.aaf.misc.rosetta.InXML;
+import org.onap.aaf.misc.rosetta.JaxInfo;
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.OutXML;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.marshal.DocMarshal;
+
+public class RosettaDF<T> extends BaseDataFactory implements DataFactory<T> {
+
+ static InJson inJSON = new InJson();
+ InXML inXML;
+
+ static OutJson outJSON = new OutJson();
+ OutXML outXML;
+ static OutRaw outRAW = new OutRaw();
+
+ // Temporary until we write JAXB impl...
+ JAXBmar jaxMar;
+ JAXBumar jaxUmar;
+
+ private Parse<Reader,?> defaultIn;
+ private Out defaultOut;
+ private RosettaEnv env;
+ private TYPE inType;
+ private TYPE outType;
+ private int defOption;
+ Marshal<T> marshal = null;
+
+
+ /**
+ * Private constructor to setup Type specific data manipulators
+ * @param schema
+ * @param rootNs
+ * @param cls
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws ClassNotFoundException
+ * @throws ParseException
+ * @throws JAXBException
+ */
+ // package on purpose
+ RosettaDF(RosettaEnv env, Schema schema, String rootNs, Class<T> cls) throws APIException {
+ this.env = env;
+ try {
+ // Note: rootNs can be null, in order to derive content from Class.
+ JaxInfo ji = rootNs==null?JaxInfo.build(cls):JaxInfo.build(cls,rootNs);
+ // Note: JAXBmar sets qname to null if not exists
+ jaxMar = new JAXBmar(rootNs==null?null:new QName("xmlns",rootNs),cls);
+ // Note: JAXBumar sets schema to null if not exists
+ jaxUmar = new JAXBumar(schema, cls);
+
+ defaultIn = inXML = new InXML(ji);
+ defaultOut = outXML = new OutXML(ji);
+ inType=outType=Data.TYPE.XML;
+ defOption = 0;
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+
+ // @Override
+ public RosettaData<T> newData() {
+ RosettaData<T> data = new RosettaData<T>(env, this)
+ .in(inType)
+ .out(outType)
+ .option(defOption);
+ return data;
+ }
+
+ // @Override
+ public RosettaData<T> newData(Env trans) {
+ RosettaData<T> data = new RosettaData<T>(trans, this)
+ .in(inType)
+ .out(outType)
+ .option(defOption);
+ return data;
+ }
+
+ @SuppressWarnings("unchecked")
+ // @Override
+ public Class<T> getTypeClass() {
+ return (Class<T>)jaxMar.getMarshalClass();
+ }
+
+ public RosettaDF<T> in(Data.TYPE type) {
+ inType = type;
+ defaultIn=getIn(type==Data.TYPE.DEFAULT?Data.TYPE.JSON:type);
+ return this;
+ }
+
+ /**
+ * If exists, first option is "Pretty", second is "Fragment"
+ *
+ * @param options
+ * @return
+ */
+ public RosettaDF<T> out(Data.TYPE type) {
+ outType = type;
+ defaultOut = getOut(type==Data.TYPE.DEFAULT?Data.TYPE.JSON:type);
+ return this;
+ }
+
+ public Parse<Reader,?> getIn(Data.TYPE type) {
+ switch(type) {
+ case DEFAULT:
+ return defaultIn;
+ case JSON:
+ return inJSON;
+ case XML:
+ return inXML;
+ default:
+ return defaultIn;
+ }
+ }
+
+ public Out getOut(Data.TYPE type) {
+ switch(type) {
+ case DEFAULT:
+ return defaultOut;
+ case JSON:
+ return outJSON;
+ case XML:
+ return outXML;
+ case RAW:
+ return outRAW;
+ default:
+ return defaultOut;
+ }
+ }
+
+ public int logType(org.onap.aaf.misc.env.Data.TYPE ot) {
+ switch(ot) {
+ case JSON:
+ return Env.JSON;
+ default:
+ return Env.XML;
+ }
+ }
+
+
+ public RosettaEnv getEnv() {
+ return env;
+ }
+
+
+ public Data.TYPE getInType() {
+ return inType;
+ }
+
+ public Data.TYPE getOutType() {
+ return outType;
+ }
+
+ public RosettaDF<T> option(int option) {
+ defOption = option;
+
+ return this;
+ }
+
+ /**
+ * Assigning Root Marshal Object
+ *
+ * Will wrap with DocMarshal Object if not already
+ *
+ * @param marshal
+ * @return
+ */
+ public RosettaDF<T> rootMarshal(Marshal<T> marshal) {
+ if(marshal instanceof DocMarshal) {
+ this.marshal = marshal;
+ } else {
+ this.marshal = DocMarshal.root(marshal);
+ }
+ return this;
+ }
+
+ public void direct(Trans trans, T t, OutputStream os, boolean ... options) throws APIException, IOException {
+ Out out = getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(marshal==null) { // Unknown marshaller... do working XML marshal/extraction
+ StringWriter sw = new StringWriter();
+ jaxMar.marshal(trans.debug(), t, sw, options);
+ out.extract(new StringReader(sw.toString()), new OutputStreamWriter(os), inXML,options);
+ } else {
+ out.extract(t, new OutputStreamWriter(os), marshal,options);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public void direct(Trans trans, T t, Writer writer, boolean ... options) throws APIException, IOException {
+ Out out = getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(marshal==null) { // Unknown marshaller... do working XML marshal/extraction
+ StringWriter sw = new StringWriter();
+ jaxMar.marshal(trans.debug(), t, sw, options);
+ out.extract(new StringReader(sw.toString()), writer, inXML,options);
+ } else {
+ out.extract(t, writer, marshal,options);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaData.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaData.java
new file mode 100644
index 0000000..446c3c9
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaData.java
@@ -0,0 +1,312 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.env;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.Saved;
+
+public class RosettaData<T> implements Data<T>{
+ private Env trans;
+ private RosettaDF<T> df;
+ private Saved saved;
+ private TYPE inType, outType;
+ // Note: This is an array of boolean in order to pass into other methods
+ private boolean options[] = new boolean[] {false, false};
+ // Temp Storage of XML. Only when we must use JAXB to read in Objects
+ private String xml,json;
+
+ // package on purpose
+ RosettaData(Env env, RosettaDF<T> rosettaDF) {
+ df = rosettaDF;
+ saved = new Saved(); // Note: Saved constructs storage as needed...
+ trans = env;
+ inType = df.getInType();
+ outType = df.getOutType(); // take defaults
+ }
+
+// // @Override
+ public RosettaData<T> in(TYPE rosettaType) {
+ inType = rosettaType;
+ return this;
+ }
+
+// // @Override
+ public RosettaData<T> out(TYPE rosettaType) {
+ outType = rosettaType;
+ return this;
+ }
+
+// // @Override
+ public RosettaData<T> load(Reader rdr) throws APIException {
+ Parse<Reader,?> in = df.getIn(inType);
+ TimeTaken tt = in.start(trans);
+ try {
+ saved.extract(rdr, (Writer)null, in);
+ xml=json=null;
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ // @Override
+ public RosettaData<T> load(InputStream is) throws APIException {
+ Parse<Reader,?> in = df.getIn(inType);
+ TimeTaken tt = in.start(trans);
+ try {
+ saved.extract(new InputStreamReader(is), (Writer)null, in);
+ xml=json=null;
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ // @Override
+ public RosettaData<T> load(String str) throws APIException {
+ Parse<Reader,?> in = df.getIn(inType);
+ TimeTaken tt = in.start(trans);
+ try {
+ saved.extract(new StringReader(str), (Writer)null, in);
+ switch(inType) {
+ case XML:
+ xml = str;
+ break;
+ case JSON:
+ json = str;
+ break;
+ default:
+
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ // @Override
+ public RosettaData<T> load(T t) throws APIException {
+ Parse<?,?> in = df.getIn(inType);
+ TimeTaken tt = in.start(trans);
+ try {
+ if(df.marshal==null) { // Unknown marshaller... do working XML marshal/extraction
+ StringWriter sw = new StringWriter();
+ df.jaxMar.marshal(trans.debug(), t, sw, options);
+ saved.extract(new StringReader(xml = sw.toString()), (Writer)null, df.inXML);
+ } else {
+ saved.extract(t, (Writer)null, df.marshal);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ public Saved getEvents() {
+ return saved;
+ }
+
+ // @Override
+ public T asObject() throws APIException {
+ Out out = df.getOut(TYPE.XML);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ //TODO Replace JAXB with Direct Object method!!!
+ StringWriter sw = new StringWriter();
+ out.extract(null, sw, saved);
+ return df.jaxUmar.unmarshal(trans.debug(), sw.toString());
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ // @Override
+ public String asString() throws APIException {
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(outType==TYPE.XML) {
+ if(xml==null) {
+ StringWriter sw = new StringWriter();
+ out.extract(null, sw, saved, options);
+ xml = sw.toString();
+ }
+ return xml;
+ } else { // is JSON
+ if(json==null) {
+ StringWriter sw = new StringWriter();
+ out.extract(null, sw, saved, options);
+ json = sw.toString();
+ }
+ return json;
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+ // @Override
+ public RosettaData<T> to(OutputStream os) throws APIException, IOException {
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(outType==TYPE.XML && xml!=null) {
+ os.write(xml.getBytes());
+ } else if(outType==TYPE.JSON && json!=null) {
+ os.write(json.getBytes());
+ } else {
+ out.extract(null, os, saved, options);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ // @Override
+ public RosettaData<T> to(Writer writer) throws APIException, IOException {
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(outType==TYPE.XML && xml!=null) {
+ writer.append(xml);
+ } else if(outType==TYPE.JSON && json!=null) {
+ writer.append(json);
+ } else {
+ out.extract(null, writer, saved, options);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ return this;
+ }
+
+ // @Override
+ public Class<T> getTypeClass() {
+ return df.getTypeClass();
+ }
+
+ private static final boolean[] emptyOption = new boolean[0];
+
+ public void direct(InputStream is, OutputStream os) throws APIException, IOException {
+ direct(is,os,emptyOption);
+ }
+
+ public void direct(Reader reader, Writer writer, boolean ... options) throws APIException, IOException {
+ Parse<Reader,?> in = df.getIn(inType);
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ out.extract(reader, writer, in,options);
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public void direct(T t, Writer writer, boolean ... options) throws APIException, IOException {
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(df.marshal==null) { // Unknown marshaller... do working XML marshal/extraction
+ StringWriter sw = new StringWriter();
+ df.jaxMar.marshal(trans.debug(), t, sw, options);
+ out.extract(new StringReader(xml = sw.toString()), writer, df.inXML,options);
+ } else {
+ out.extract(t, writer, df.marshal,options);
+ }
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public void direct(T t, OutputStream os, boolean ... options) throws APIException, IOException {
+ Out out = df.getOut(outType);
+ TimeTaken tt = trans.start(out.logName(),df.logType(outType)); // determine from Out.. without dependency on Env?
+ try {
+ if(df.marshal==null) { // Unknown marshaller... do working XML marshal/extraction
+ if(outType.equals(TYPE.XML)) {
+ df.jaxMar.marshal(trans.debug(), t, os, options);
+ } else {
+ StringWriter sw = new StringWriter();
+ df.jaxMar.marshal(trans.debug(), t, sw, options);
+ out.extract(new StringReader(xml = sw.toString()), new OutputStreamWriter(os), df.inXML,options);
+ }
+ } else {
+ out.extract(t, new OutputStreamWriter(os), df.marshal,options);
+ }
+
+ } catch (Exception e) {
+ throw new APIException(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+ public void direct(InputStream is, OutputStream os, boolean ... options) throws APIException, IOException {
+ direct(new InputStreamReader(is),new OutputStreamWriter(os), options);
+ }
+
+ // // @Override
+ public RosettaData<T> option(int option) {
+ options[0] = (option&Data.PRETTY)==Data.PRETTY;
+ options[1] = (option&Data.FRAGMENT)==Data.FRAGMENT;
+ return this;
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaEnv.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaEnv.java
new file mode 100644
index 0000000..05c75b7
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/env/RosettaEnv.java
@@ -0,0 +1,89 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.env;
+
+import java.applet.Applet;
+import java.util.Properties;
+
+import javax.xml.namespace.QName;
+import javax.xml.validation.Schema;
+
+import org.onap.aaf.misc.env.APIException;
+
+/**
+ * An essential Implementation of Env, which will fully function, without any sort
+ * of configuration.
+ *
+ * Use as a basis for Group level Env, just overriding where needed.
+ * @author Jonathan
+ *
+ */
+public class RosettaEnv extends org.onap.aaf.misc.env.impl.BasicEnv {
+
+ public RosettaEnv() {
+ super();
+ }
+
+ public RosettaEnv(Applet applet, String... tags) {
+ super(applet, tags);
+ }
+
+ public RosettaEnv(String[] args) {
+ super(args);
+ }
+
+ public RosettaEnv(String tag, String[] args) {
+ super(tag, args);
+ }
+
+ public RosettaEnv(String tag, Properties props) {
+ super(tag, props);
+ }
+
+ public RosettaEnv(Properties props) {
+ super(props);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> RosettaDF<T> newDataFactory(Class<?>... classes) throws APIException {
+ return new RosettaDF<T>(this, null, null, (Class<T>)classes[0]);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> RosettaDF<T> newDataFactory(Schema schema, Class<?>... classes) throws APIException {
+ return new RosettaDF<T>(this, schema, null, (Class<T>)classes[0]);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public<T> RosettaDF<T> newDataFactory(QName qName, Class<?> ... classes) throws APIException {
+ return new RosettaDF<T>(this, null, qName.getNamespaceURI(),(Class<T>)classes[0]);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public<T> RosettaDF<T> newDataFactory(Schema schema, QName qName, Class<?> ... classes) throws APIException {
+ return new RosettaDF<T>(this, schema,qName.getNamespaceURI(),(Class<T>)classes[0]);
+ }
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DataWriter.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DataWriter.java
new file mode 100644
index 0000000..1655928
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DataWriter.java
@@ -0,0 +1,139 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+/**
+ * We make these objects instead of static functions so they can be passed into
+ * FieldArray.
+ *
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public abstract class DataWriter<T> {
+ public abstract boolean write(T t, StringBuilder sb);
+
+ public final static DataWriter<String> STRING = new DataWriter<String>() {
+ @Override
+ public boolean write(String s, StringBuilder sb) {
+ sb.append(s);
+ return true;
+ }
+ };
+
+ public final static DataWriter<Integer> INTEGER = new DataWriter<Integer>() {
+ @Override
+ public boolean write(Integer i, StringBuilder sb) {
+ sb.append(i);
+ return false;
+ }
+ };
+
+ public final static DataWriter<Long> LONG = new DataWriter<Long>() {
+ @Override
+ public boolean write(Long t, StringBuilder sb) {
+ sb.append(t);
+ return false;
+ }
+ };
+
+ public final static DataWriter<Byte> BYTE = new DataWriter<Byte>() {
+ @Override
+ public boolean write(Byte t, StringBuilder sb) {
+ sb.append(t);
+ return false;
+ }
+ };
+
+ public final static DataWriter<Character> CHAR = new DataWriter<Character>() {
+ @Override
+ public boolean write(Character t, StringBuilder sb) {
+ sb.append(t);
+ return true;
+ }
+ };
+
+ public final static DataWriter<Boolean> BOOL = new DataWriter<Boolean>() {
+ @Override
+ public boolean write(Boolean t, StringBuilder sb) {
+ sb.append(t);
+ return true;
+ }
+ };
+
+
+ /*
+ public final static DataWriter<byte[]> BYTE_ARRAY = new DataWriter<byte[]>() {
+ @Override
+ public boolean write(byte[] ba, StringBuilder sb) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(ba);
+ StringBuilderOutputStream sbos = new StringBuilderOutputStream(sb);
+// try {
+ //TODO find Base64
+// Symm.base64noSplit().encode(bais, sbos);
+// } catch (IOException e) {
+// // leave blank
+// }
+ return true;
+ }
+
+ };
+ */
+
+ public final static DataWriter<XMLGregorianCalendar> DATE = new DataWriter<XMLGregorianCalendar>() {
+ @Override
+ public boolean write(XMLGregorianCalendar t, StringBuilder sb) {
+ sb.append(Chrono.dateOnlyStamp(t));
+ return true;
+ }
+ };
+
+ public final static DataWriter<XMLGregorianCalendar> DATE_TIME = new DataWriter<XMLGregorianCalendar>() {
+ @Override
+ public boolean write(XMLGregorianCalendar t, StringBuilder sb) {
+ sb.append(Chrono.dateTime(t));
+ return true;
+ }
+ };
+
+ private static final char[] chars="0123456789ABCDEF".toCharArray();
+ public final static DataWriter<byte[]> HEX_BINARY = new DataWriter<byte[]>() {
+ @Override
+ public boolean write(byte[] ba, StringBuilder sb) {
+ // FYI, doing this because don't want intermediate
+ // String in "HexString" or the processing in
+ // "String.format"
+ //sb.append("0x");
+ for(int i=0;i<ba.length;++i) {
+ byte b = ba[i];
+ sb.append(chars[((b&0xF0)>>4)]);
+ sb.append(chars[b&0xF]);
+ }
+ return true;
+ }
+ };
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DocMarshal.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DocMarshal.java
new file mode 100644
index 0000000..5249a17
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/DocMarshal.java
@@ -0,0 +1,82 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import java.util.Iterator;
+
+import org.onap.aaf.misc.rosetta.Ladder;
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+public class DocMarshal<T> extends Marshal<T> {
+ private Marshal<T> root;
+
+ public DocMarshal(Marshal<T> root) {
+ this.root = root;
+ }
+
+ @Override
+ public Parsed<State> parse(T t, Parsed<State> parsed) throws ParseException {
+ Ladder<Iterator<?>> ladder = parsed.state.ladder;
+ Iterator<?> iter = ladder.peek();
+ if(iter==null) {
+ ladder.push(PENDING_ITERATOR);
+ parsed.event = START_DOC;
+ } else if (DONE_ITERATOR.equals(iter)) {
+ } else {
+ ladder.ascend(); // look at field info
+ Iterator<?> currFieldIter = ladder.peek();
+ if(!DONE_ITERATOR.equals(currFieldIter)){
+ parsed = root.parse(t, parsed);
+ }
+ ladder.descend();
+ if(DONE_ITERATOR.equals(currFieldIter) || parsed.event==NONE) {
+ parsed.event = END_DOC;
+ ladder.push(DONE_ITERATOR);
+ }
+ }
+ return parsed; // if unchanged, then it will end process
+
+ }
+
+ public static final Iterator<Void> PENDING_ITERATOR = new Iterator<Void>() {
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+
+ @Override
+ public Void next() {
+ return null;
+ }
+
+ @Override
+ public void remove() {
+ }
+ };
+
+ public static<T> DocMarshal<T> root(Marshal<T> m) {
+ return (DocMarshal<T>)new DocMarshal<T>(m);
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldArray.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldArray.java
new file mode 100644
index 0000000..3006f89
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldArray.java
@@ -0,0 +1,92 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.onap.aaf.misc.rosetta.Ladder;
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+
+public abstract class FieldArray<T,S> extends Marshal<T> {
+ private DataWriter<S> dataWriter;
+ private String name;
+
+ public FieldArray(String name, DataWriter<S> dw) {
+ this.name = name;
+ dataWriter = dw;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Parsed<State> parse(T t, Parsed<State> parsed) throws ParseException {
+ Ladder<Iterator<?>> ladder = parsed.state.ladder;
+ Iterator<?> iter = ladder.peek();
+ if(iter==null) {
+ List<S> list = data(t);
+ if(list.isEmpty() && parsed.state.smallest) {
+ ladder.push(DONE_ITERATOR);
+ } else {
+ ladder.push(new ListIterator<S>(list));
+ parsed.event = START_ARRAY;
+ parsed.name = name;
+ }
+ } else if (DONE_ITERATOR.equals(iter)) {
+ } else {
+ ladder.ascend(); // look at field info
+ Iterator<?> memIter = ladder.peek();
+ ListIterator<S> mems = (ListIterator<S>)iter;
+ S mem;
+ if(memIter==null) {
+ mem=mems.next();
+ } else if(!DONE_ITERATOR.equals(memIter)) {
+ mem=mems.peek();
+ } else if(iter.hasNext()) {
+ mem=null;
+ ladder.push(null);
+ } else {
+ mem=null;
+ }
+
+ if(mem!=null) {
+ parsed.isString=dataWriter.write(mem, parsed.sb);
+ parsed.event = NEXT;
+ }
+ ladder.descend();
+ if(mem==null) {
+ if(iter.hasNext()) {
+ parsed.event = NEXT;
+ } else {
+ parsed.event = END_ARRAY;
+ ladder.push(DONE_ITERATOR);
+ }
+ }
+ }
+ return parsed; // if unchanged, then it will end process
+ }
+
+ protected abstract List<S> data(T t);
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldBlob.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldBlob.java
new file mode 100644
index 0000000..1de14e8
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldBlob.java
@@ -0,0 +1,38 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+public abstract class FieldBlob<T> extends FieldMarshal<T>{
+ public FieldBlob(String name) {
+ super(name);
+ }
+
+ protected abstract byte[] data(T t);
+
+ @Override
+ protected boolean data(T t, StringBuilder sb) {
+ return false;
+ // unimplemented
+ //return DataWriter.BYTE_ARRAY.write(data(t),sb);
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDate.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDate.java
new file mode 100644
index 0000000..b3632a1
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDate.java
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public abstract class FieldDate<T> extends FieldMarshal<T> {
+ public FieldDate(String name) {
+ super(name);
+ }
+
+ @Override
+ final protected boolean data(T t, StringBuilder sb) {
+ return DataWriter.DATE.write(data(t), sb);
+ }
+
+ protected abstract XMLGregorianCalendar data(T t);
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDateTime.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDateTime.java
new file mode 100644
index 0000000..8aa2982
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldDateTime.java
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public abstract class FieldDateTime<T> extends FieldMarshal<T> {
+ public FieldDateTime(String name) {
+ super(name);
+ }
+
+ @Override
+ final protected boolean data(T t, StringBuilder sb) {
+ return DataWriter.DATE_TIME.write(data(t), sb);
+ }
+
+ protected abstract XMLGregorianCalendar data(T t);
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldHexBinary.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldHexBinary.java
new file mode 100644
index 0000000..589d092
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldHexBinary.java
@@ -0,0 +1,35 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+public abstract class FieldHexBinary<T> extends FieldMarshal<T>{
+ public FieldHexBinary(String name) {
+ super(name);
+ }
+
+ protected abstract byte[] data(T t);
+
+ @Override
+ protected boolean data(T t, StringBuilder sb) {
+ return DataWriter.HEX_BINARY.write(data(t), sb);
+ }
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldMarshal.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldMarshal.java
new file mode 100644
index 0000000..cb8b655
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldMarshal.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+public abstract class FieldMarshal<T> extends Marshal<T> {
+ private String name;
+
+ public FieldMarshal(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Parsed<State> parse(T t, Parsed<State> parsed) {
+ parsed.state.ladder.push(DONE_ITERATOR);
+ parsed.event = Parse.NEXT;
+ parsed.name = name;
+ parsed.isString = data(t,parsed.sb);
+ return parsed;
+ }
+
+ /**
+ * Write Value to StringBuilder
+ * Return true if value looks like a String
+ * false if it is Numeric
+ * @param t
+ * @param sb
+ * @return
+ */
+ protected abstract boolean data(T t, StringBuilder sb);
+
+}
\ No newline at end of file
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldNumeric.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldNumeric.java
new file mode 100644
index 0000000..aac9ac6
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldNumeric.java
@@ -0,0 +1,36 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+public abstract class FieldNumeric<N,T> extends FieldMarshal<T> {
+ public FieldNumeric(String name) {
+ super(name);
+ }
+
+ @Override
+ final protected boolean data(T t, StringBuilder sb) {
+ sb.append(data(t));
+ return false;
+ }
+
+ protected abstract N data(T t);
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldString.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldString.java
new file mode 100644
index 0000000..2337c3c
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/FieldString.java
@@ -0,0 +1,36 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+public abstract class FieldString<T> extends FieldMarshal<T> {
+ public FieldString(String name) {
+ super(name);
+ }
+
+ protected abstract String data(T t);
+
+ @Override
+ final protected boolean data(T t, StringBuilder sb) {
+ return DataWriter.STRING.write(data(t), sb);
+ }
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ListIterator.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ListIterator.java
new file mode 100644
index 0000000..6045141
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ListIterator.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Need an Iterator that can peek the current value without changing
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+final class ListIterator<T> implements Iterator<T> {
+ private T curr;
+ private Iterator<T> delg;
+ public ListIterator(List<T> list) {
+ curr = null;
+ delg = list.iterator();
+ }
+ @Override
+ public boolean hasNext() {
+ return delg.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return curr = delg.hasNext()?delg.next():null;
+ }
+
+ public T peek() {
+ return curr==null?next():curr;
+ }
+
+ @Override
+ public void remove() {
+ delg.remove();
+ }
+
+}
\ No newline at end of file
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjArray.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjArray.java
new file mode 100644
index 0000000..3d7d1b4
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjArray.java
@@ -0,0 +1,90 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.onap.aaf.misc.rosetta.Ladder;
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+
+public abstract class ObjArray<T,S> extends Marshal<T> {
+ private String name;
+ private Marshal<S> subMarshaller;
+
+ public ObjArray(String name, Marshal<S> subMarshaller) {
+ this.name = name;
+ this.subMarshaller = subMarshaller;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Parsed<State> parse(T t, Parsed<State> parsed) throws ParseException {
+ Ladder<Iterator<?>> ladder = parsed.state.ladder;
+ Iterator<?> iter = ladder.peek();
+ if(iter==null) {
+ List<S> list = data(t);
+ if(list.isEmpty() && parsed.state.smallest) {
+ ladder.push(DONE_ITERATOR);
+ } else {
+ ladder.push(new ListIterator<S>(list));
+ parsed.event = START_ARRAY;
+ parsed.name = name;
+ }
+ } else if (DONE_ITERATOR.equals(iter)) {
+ } else {
+ ladder.ascend(); // look at field info
+ Iterator<?> memIter = ladder.peek();
+ ListIterator<S> mems = (ListIterator<S>)iter;
+ S mem;
+ if(memIter==null) {
+ mem=mems.next();
+ } else if(!DONE_ITERATOR.equals(memIter)) {
+ mem=mems.peek();
+ } else if(iter.hasNext()) {
+ mem=null;
+ ladder.push(null);
+ } else {
+ mem=null;
+ }
+
+ if(mem!=null)
+ parsed = subMarshaller.parse(mem, parsed);
+ ladder.descend();
+ if(mem==null) {
+ if(iter.hasNext()) {
+ parsed.event = NEXT;
+ } else {
+ parsed.event = END_ARRAY;
+ ladder.push(DONE_ITERATOR);
+ }
+ }
+ }
+ return parsed; // if unchanged, then it will end process
+ }
+
+ protected abstract List<S> data(T t);
+
+}
diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjMarshal.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjMarshal.java
new file mode 100644
index 0000000..eaa7a74
--- /dev/null
+++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/marshal/ObjMarshal.java
@@ -0,0 +1,128 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.marshal;
+
+import java.util.Iterator;
+
+import org.onap.aaf.misc.rosetta.Ladder;
+import org.onap.aaf.misc.rosetta.Marshal;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+/**
+ * Object Marshal
+ * Assumes has Fields and other Objects
+ * s
+ * @author Jonathan
+ *
+ * @param <T>
+ */
+public abstract class ObjMarshal<T> extends Marshal<T> {
+ // Note: Not Using List or ArrayList, because there is no "Peek" concept in their iterator.
+ private Marshal<T>[] pml;
+ private int end=0;
+
+ /**
+ * @param pm
+ */
+ @SuppressWarnings("unchecked")
+ protected void add(Marshal<T> pm) {
+ if(pml==null) {
+ pml = new Marshal[Ladder.DEFAULT_INIT_SIZE];
+ } else if(end>pml.length) {
+ Object temp[] = pml;
+ pml = new Marshal[pml.length+Ladder.DEFAULT_INIT_SIZE];
+ System.arraycopy(temp, 0, pml, 0, pml.length);
+ }
+ pml[end]=pm;
+ ++end;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.rosetta.Parse#parse(java.lang.Object, org.onap.aaf.misc.rosetta.Parsed)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Parsed<State> parse(T in, Parsed<State> parsed) throws ParseException {
+ Ladder<Iterator<?>> ladder = parsed.state.ladder;
+ Iterator<Marshal<T>> iter = (Iterator<Marshal<T>>)ladder.peek();
+ if(iter==null) {
+ if(pml.length>0) {
+ ladder.push(new FieldsIterator());
+ parsed.event = START_OBJ;
+ } else {
+ ladder.push(DONE_ITERATOR);
+ }
+ } else if (DONE_ITERATOR.equals(iter)) {
+ } else {
+ FieldsIterator fields = (FieldsIterator)iter;
+ ladder.ascend(); // look at field info
+ Iterator<?> currFieldIter = ladder.peek();
+ Marshal<T> marshal;
+ if(currFieldIter==null) {
+ marshal=fields.next();
+ } else if(!DONE_ITERATOR.equals(currFieldIter)) {
+ marshal=fields.peek();
+ if(marshal==null && fields.hasNext())marshal=fields.next();
+ } else if(fields.hasNext()) {
+ marshal=fields.next();
+ ladder.push(null);
+ } else {
+ marshal=null;
+ }
+
+ if(marshal!=null)
+ parsed = marshal.parse(in, parsed);
+ ladder.descend();
+ if(marshal==null || parsed.event==NONE) {
+ parsed.event = END_OBJ;
+ ladder.push(DONE_ITERATOR);
+ }
+ }
+ return parsed; // if unchanged, then it will end process
+ }
+
+ private class FieldsIterator implements Iterator<Marshal<T>> {
+ private int idx = -1;
+
+ @Override
+ public boolean hasNext() {
+ return idx<end;
+ }
+
+ @Override
+ public Marshal<T> next() {
+ return pml[++idx];
+ }
+
+ public Marshal<T> peek() {
+ return idx<0?null:pml[idx];
+ }
+
+ @Override
+ public void remove() {
+ pml[idx]=null;
+ }
+
+ }
+
+}
diff --git a/misc/rosetta/src/main/xsd/inherit.xsd b/misc/rosetta/src/main/xsd/inherit.xsd
new file mode 100644
index 0000000..e0a33fb
--- /dev/null
+++ b/misc/rosetta/src/main/xsd/inherit.xsd
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="urn:inherit"
+ xmlns="urn:inherit"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ >
+
+ <xs:complexType name="baseType">
+ <xs:sequence>
+ <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="num" type="xs:short" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="derivedA">
+ <xs:annotation>
+ <xs:documentation>Select one of the items</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="baseType">
+ <xs:sequence>
+ <xs:element name="shortName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="value" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="base" type="baseType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
\ No newline at end of file
diff --git a/misc/rosetta/src/main/xsd/s.xsd b/misc/rosetta/src/main/xsd/s.xsd
new file mode 100644
index 0000000..b4d137e
--- /dev/null
+++ b/misc/rosetta/src/main/xsd/s.xsd
@@ -0,0 +1,64 @@
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="urn:s:xsd"
+ xmlns:s="urn:s:xsd"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ >
+
+ <xs:element name="SampleData">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="date" type="xs:long"/>
+ <xs:element name="item" type="xs:string" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="LargerData">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="s:SampleData" minOccurs="1" maxOccurs="unbounded"/>
+ <xs:element name="fluff" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="LargerDatas">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="s:LargerData" minOccurs="1" maxOccurs = "unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+
+ <xs:element name="Multi">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="f1" type="xs:string" minOccurs="0" maxOccurs = "unbounded"/>
+ <xs:element name="f2" type="xs:string" minOccurs="0" maxOccurs = "unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
\ No newline at end of file
diff --git a/misc/rosetta/src/main/xsd/types.xsd b/misc/rosetta/src/main/xsd/types.xsd
new file mode 100644
index 0000000..5533964
--- /dev/null
+++ b/misc/rosetta/src/main/xsd/types.xsd
@@ -0,0 +1,46 @@
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<xs:schema elementFormDefault="qualified"
+ targetNamespace="urn:types:xsd"
+ xmlns:s="urn:types:xsd"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ >
+ <xs:element name="multi">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="single" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="str" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="int" type="xs:int" minOccurs="1" maxOccurs="1" />
+ <xs:element name="long" type="xs:long" minOccurs="1" maxOccurs="1" />
+ <xs:element name="date" type="xs:date" minOccurs="1" maxOccurs="1" />
+ <xs:element name="datetime" type="xs:dateTime" minOccurs="1" maxOccurs="1" />
+ <xs:element name="binary" type="xs:hexBinary" minOccurs="1" maxOccurs="1" />
+ <xs:element name="array" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
\ No newline at end of file
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromJSON.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromJSON.java
new file mode 100644
index 0000000..121deea
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromJSON.java
@@ -0,0 +1,268 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.impl.EnvFactory;
+import org.onap.aaf.misc.env.jaxb.JAXBmar;
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.rosetta.InJson;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.OutXML;
+
+import junit.framework.Assert;
+import s.xsd.LargerData;
+import s.xsd.SampleData;
+
+public class JU_FromJSON {
+ private static int ITERATIONS = 10000;
+ static String str = "{\"SampleData\":[" +
+ "{\"id\":\"sd object \\\"1\\\"\",\"date\":1316084944213,\"item\":[\"Item 1.1\",\"Item 1.2\"]}," +
+ "{\"id\":\"sd object \\\"2\\\"\",\"date\":1316084945343,\"item\":[\"Item 2.1\",\"Item 2.2\"]}],\"fluff\":\"MyFluff\"}";
+ InJson inJSON = new InJson();
+
+ @Test
+ public void rawParse() throws Exception {
+ System.out.println("*** PARSE JSON -> RAW Dump ***");
+ System.out.println(str);
+ StringBuilderWriter sbw = new StringBuilderWriter();
+ new OutRaw().extract(new StringReader(str),sbw,inJSON);
+ System.out.println(sbw.getBuffer());
+ }
+
+ @Test
+ public void parseJSON2Dump() throws Exception {
+ System.out.println("*** PARSE JSON -> Dump ***");
+ System.out.println(str);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ new OutDump().extract(new StringReader(str), sbw, inJSON);
+
+ System.out.println(sbw.getBuffer());
+ }
+
+ @Test
+ public void nonprettyJSON() throws Exception {
+ System.out.println("*** JSON -> (Intermediate Stream) -> Non-pretty JSON ***");
+ System.out.println(str);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Out jout = new OutJson();
+ Trans trans;
+ Report report = new Report(ITERATIONS,"JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(str);
+ TimeTaken tt = trans.start("Parse JSON", Env.JSON);
+ try {
+ jout.extract(sr, sbw, inJSON);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.JSON);
+ } while(report.go());
+
+ String result = sbw.toString();
+ System.out.println(result);
+ Assert.assertEquals(result, str);
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+ @Test
+ public void parseJSON2JSON() throws Exception {
+ System.out.println("*** JSON -> (Intermediate Stream) -> Pretty JSON ***");
+ System.out.println(str);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Out jout = new OutJson();
+ Trans trans;
+ Report report = new Report(ITERATIONS,"JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(str);
+ TimeTaken tt = trans.start("Parse JSON", Env.JSON);
+ try {
+ jout.extract(sr, sbw, inJSON,true);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.JSON);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+ @Test
+ public void parseJSON2XML() throws Exception {
+ System.out.println("*** PARSE JSON -> XML ***");
+ System.out.println(str);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Out xout = new OutXML("LargerData","xmlns=urn:s:xsd");
+ Trans trans;
+ Report report = new Report(ITERATIONS,"JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(str);
+ TimeTaken tt = trans.start("Parse JSON", Env.JSON);
+ try {
+ xout.extract(sr, sbw, inJSON);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.JSON);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+ @Test
+ public void parseJSON2PrettyXML() throws Exception {
+ System.out.println("*** PARSE JSON -> Pretty XML ***");
+ System.out.println(str);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+ IndentPrintWriter ipw = new IndentPrintWriter(sbw);
+
+ Out xout = new OutXML("LargerData","xmlns=urn:s:xsd");
+ Trans trans;
+ Report report = new Report(ITERATIONS,"JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(str);
+ TimeTaken tt = trans.start("Parse JSON", Env.JSON);
+ try {
+ xout.extract(sr, ipw, inJSON);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.JSON);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+
+ @Test
+ public void jaxbObj2XML() throws Exception {
+ System.out.println("*** JAXB Object -> XML ***");
+
+ LargerData ld = new LargerData();
+ SampleData sd = new SampleData();
+ sd.setDate(System.currentTimeMillis());
+ sd.setId("sd object \"1\"");
+ sd.getItem().add("Item 1.1");
+ sd.getItem().add("Item 1.2");
+ ld.getSampleData().add(sd);
+ sd = new SampleData();
+ sd.setDate(System.currentTimeMillis());
+ sd.setId("sd object \"2\"");
+ sd.getItem().add("Item 2.1");
+ sd.getItem().add("Item 2.2");
+ ld.getSampleData().add(sd);
+ ld.setFluff("MyFluff");
+
+ JAXBmar jaxBmar = new JAXBmar(LargerData.class);
+ //jaxBmar.asFragment(true);
+ //jaxBmar.pretty(true);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ TimeTaken tt = trans.start("JAXB", Env.XML);
+ try {
+ jaxBmar.marshal(LogTarget.NULL, ld, sbw);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+ @Test
+ public void jaxbObj2PrettyXML() throws Exception {
+ System.out.println("*** JAXB Object -> Pretty XML ***");
+
+ LargerData ld = new LargerData();
+ SampleData sd = new SampleData();
+ sd.setDate(System.currentTimeMillis());
+ sd.setId("sd object \"1\"");
+ sd.getItem().add("Item 1.1");
+ sd.getItem().add("Item 1.2");
+ ld.getSampleData().add(sd);
+ sd = new SampleData();
+ sd.setDate(System.currentTimeMillis());
+ sd.setId("sd object \"2\"");
+ sd.getItem().add("Item 2.1");
+ sd.getItem().add("Item 2.2");
+ ld.getSampleData().add(sd);
+ ld.setFluff("MyFluff");
+
+ JAXBmar jaxBmar = new JAXBmar(LargerData.class);
+ //jaxBmar.asFragment(true);
+ jaxBmar.pretty(true);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ TimeTaken tt = trans.start("JAXB", Env.XML);
+ try {
+ jaxBmar.marshal(LogTarget.NULL, ld, sbw);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromXML.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromXML.java
new file mode 100644
index 0000000..5881362
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_FromXML.java
@@ -0,0 +1,259 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Trans.Metric;
+import org.onap.aaf.misc.env.impl.EnvFactory;
+import org.onap.aaf.misc.env.jaxb.JAXBmar;
+import org.onap.aaf.misc.env.jaxb.JAXBumar;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.rosetta.InXML;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.OutXML;
+
+import s.xsd.LargerData;
+
+public class JU_FromXML {
+ private static int ITERATIONS = 1;
+ ;
+
+ private final static String xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
+ "<LargerData xmlns=\"urn:s:xsd\">\n" +
+ " <SampleData>\n" +
+ " <id>sd object 1</id>\n" +
+ " <date>1346765355134</date>\n" +
+ " <item>Item 1.1</item>\n" +
+ " <item>Item 1.2</item>\n" +
+ " </SampleData>\n" +
+ " <SampleData>\n" +
+ " <id>sd object 2</id>\n" +
+ " <date>1346765355134</date>\n" +
+ " <item>Item 2.1</item>\n" +
+ " <item>Item 2.2</item>\n" +
+ " </SampleData>\n" +
+ " <fluff>MyFluff</fluff>\n" +
+ "</LargerData>\n";
+
+
+ @Test
+ public void test() throws Exception {
+ InXML inXML = new InXML(LargerData.class);
+
+ System.out.println(xml);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Reader rdr = new StringReader(xml);
+
+ new OutRaw().extract(rdr, sbw, inXML);
+ System.out.println(sbw.getBuffer());
+ }
+
+
+ @Test
+ public void xml2JSON() throws Exception {
+ System.out.println("*** XML -> JSON (No Warm up) ***");
+ Out jout = new OutJson();
+ InXML inXML = new InXML(LargerData.class);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(xml);
+ TimeTaken tt = trans.start("Parse XML", Env.XML);
+ try {
+ jout.extract(sr, sbw, inXML);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+ @Test
+ public void xml2XML() throws Exception {
+ System.out.println("*** XML -> (Event Queue) -> XML (No Warm up) ***");
+ Out xout = new OutXML("LargerData");
+ InXML inXML = new InXML(LargerData.class);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(xml);
+ TimeTaken tt = trans.start("Parse XML", Env.XML);
+ try {
+ xout.extract(sr, sbw, inXML);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+
+
+ @Test
+ public void warmup() throws Exception {
+ if(ITERATIONS>20) {
+ System.out.println("*** Warmup JAXB ***");
+
+ JAXBumar jaxbUmar = new JAXBumar(LargerData.class);
+ JAXBmar jaxBmar = new JAXBmar(LargerData.class);
+ //jaxBmar.asFragment(true);
+ //jaxBmar.pretty(true);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+
+ LargerData ld;
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ TimeTaken all = trans.start("Combo", Env.SUB);
+ try {
+ TimeTaken tt = trans.start("JAXB Unmarshal", Env.XML);
+ try {
+ ld = jaxbUmar.unmarshal(LogTarget.NULL, xml);
+ } finally {
+ tt.done();
+ }
+ tt = trans.start("JAXB marshal", Env.XML);
+ try {
+ jaxBmar.marshal(LogTarget.NULL, ld, sbw);
+ } finally {
+ tt.done();
+ }
+ } finally {
+ all.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+ }
+ }
+ @Test
+ public void xml2jaxb2xml() throws Exception {
+ System.out.println("*** XML -> JAXB Object -> XML ***");
+ JAXBumar jaxbUmar = new JAXBumar(LargerData.class);
+ JAXBmar jaxBmar = new JAXBmar(LargerData.class);
+ //jaxBmar.asFragment(true);
+ //jaxBmar.pretty(true);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ LargerData ld;
+ Trans trans;
+ Report report = new Report(ITERATIONS,"XML");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ TimeTaken all = trans.start("Combo", Env.SUB);
+ try {
+ TimeTaken tt = trans.start("JAXB Unmarshal", Env.XML);
+ try {
+ ld = jaxbUmar.unmarshal(LogTarget.NULL, xml);
+ } finally {
+ tt.done();
+ }
+ tt = trans.start("JAXB marshal", Env.XML);
+ try {
+ jaxBmar.marshal(LogTarget.NULL, ld, sbw);
+ } finally {
+ tt.done();
+ }
+ } finally {
+ all.done();
+ }
+ report.glean(trans,Env.XML);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString()); }
+
+ @Test
+ public void xml2jaxb2PrettyXml() throws Exception {
+ System.out.println("*** XML -> JAXB Object -> Pretty XML ***");
+ JAXBumar jaxbUmar = new JAXBumar(LargerData.class);
+ JAXBmar jaxBmar = new JAXBmar(LargerData.class);
+ //jaxBmar.asFragment(true);
+ jaxBmar.pretty(true);
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans = EnvFactory.newTrans();
+ LargerData ld;
+ for(int i=0;i<ITERATIONS;++i) {
+ sbw.reset();
+ TimeTaken all = trans.start("Combo", Env.SUB);
+ try {
+ TimeTaken tt = trans.start("JAXB Unmarshal", Env.XML);
+ try {
+ ld = jaxbUmar.unmarshal(LogTarget.NULL, xml);
+ } finally {
+ tt.done();
+ }
+ tt = trans.start("JAXB marshal", Env.XML);
+ try {
+ jaxBmar.marshal(LogTarget.NULL, ld, sbw);
+ } finally {
+ tt.done();
+ }
+ } finally {
+ all.done();
+ }
+ }
+ sbw.append('\n');
+ Metric m;
+ if(ITERATIONS>20) {
+ m = trans.auditTrail(0,null);
+ } else {
+ m = trans.auditTrail(0, sbw.getBuffer());
+ System.out.println(sbw.getBuffer());
+ }
+ System.out.println(ITERATIONS + " entries, Total Time: " + m.total + "ms, Avg Time: " + m.total/ITERATIONS + "ms");
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_JSON.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_JSON.java
new file mode 100644
index 0000000..2a48edc
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_JSON.java
@@ -0,0 +1,136 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.onap.aaf.misc.rosetta.InJson;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.ParseException;
+
+public class JU_JSON {
+
+ @Test
+ public void test() throws IOException, ParseException {
+ InJson jin = new InJson();
+ Out jout = new OutJson();
+
+ go(jin, jout, "{\"id\":\"Me, Myself\",\"date\":1353094689100}");
+
+ go(jin, jout, "{\"id\":\"My ID 1\",\"desc\":\"My Description 1\",\"comment\":[\"My Comment 1\"],\"utc\":1360418381310}");
+ go(jin, jout, "{\"id\":\"My ID 1\",\"desc\":\"My Description 1\",\"comment\":[\"My Comment 1\",\"My Comment 2\"],\"utc\":1360418381310}");
+
+ go(jin, jout, "{\"SampleData\":[" +
+ "{\"id\":\"sd object \\\"1\\\"\",\"date\":1316084944213,\"item\":[\"Item 1.1\",\"Item 1.2\"]}," +
+ "{\"id\":\"sd object \\\"2\\\"\",\"date\":1316084945343,\"item\":[\"Item 2.1\",\"Item 2.2\"]}],\"fluff\":\"MyFluff\"}"
+ );
+
+ go(jin, jout, "{\"SampleData\":[{\"date\":1316084945343}],\"fluff\":\"MyFluff\"}");
+
+ go(jin, jout, "{\"id\":\"Me,[}[eg[)(:x,\\\" Myself\",\"date\":1353094689100}");
+
+ // TODO: Clean out AT&T specific data
+ go(jin,jout, "{\"userid\":\"jg1555\",\"timestamp\":1353097388531,\"item\":[{\"tag\":\"color\",\"value\":\"Mauve\"},{\"tag\":\"shirtsize\",\"value\":\"Xtra Large\"}]}");
+ //go()
+ //"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><vote xmlns=\"urn:poll.att.com\"><userid>jg1555</userid><timestamp>1353082669667</timestamp></vote>");
+
+ // 3/11/2015 Jonathan found a case with missing comma
+ go(jin,jout, "{\"start\":\"2015-03-11T18:18:05.580-05:00\",\"end\":\"2015-09-11-05:00\",\"force\":\"false\",\"perm\":{\"type\":\"org.osaaf.myns.mytype\",\"instance\":\"myInstance\",\"action\":\"myAction\"}"
+ + ",\"role\":\"org.osaaf.myns.myrole\"}");
+
+ // 3/12/2015 Jonathan Kurt Schurenberg noticed an issue of object names in an array. This is valid code.
+ go(jin,jout, "{\"role\":[{\"name\":\"org.osaaf.myns.myrole\",\"perms\":[{\"type\":\"org.osaaf.myns.mytype\",\"instance\":\"myAction\"},{\"type\":\"org.osaaf.myns.mytype\",\"instance\":\"myOtherAction\"}]}"
+ + ",{\"name\":\"org.osaaf.myns.myOtherRole\",\"perms\":[{\"type\":\"org.osaaf.myns.myOtherType\",\"instance\":\"myAction\"},{\"type\":\"org.osaaf.myns.myOthertype\",\"instance\":\"myOtherAction\"}]}]}");
+
+ // 3/13/2015 - discovered with complex Response
+ go(jin,jout, "{\"meth\":\"GET\",\"path\":\"/authz/perms/:type\",\"desc\":\"GetPermsByType\",\"comments\":[\"List All Permissions that match :type listed\"],"
+ + "\"contentType\":[\"application/Permissions+json;q=1.0;charset=utf-8;version=1.1,application/json;q=1.0;version=1.1\""
+ + ",\"application/Perms+xml;q=1.0;charset=utf-8;version=2.0,text/xml;q=1.0;version=2.0\",\"application/Perms+json;q=1.0;charset=utf-8;version=2.0,application/json;q=1.0;version=2.0,*/*;q=1.0\""
+ + ",\"application/Permissions+xml;q=1.0;charset=utf-8;version=1.1,text/xml;q=1.0;version=1.1\"]}");
+
+
+ // Test a Windoze "Pretty Print", validate skipping of Windoze characters as well as other odd control characters listed
+ // in json.org
+ StringWriter sw = new StringWriter();
+ jout.extract(new StringReader(
+ "{\b\f\n\r\t \"id\""
+ + ":\"Me, \b\f\n\r\tMyself\",\"date\":1353094689100"
+ + "\b\f\n\r\t }"
+ ),sw,jin);
+ Assert.assertEquals("{\"id\":\"Me, \b\f\n\r\tMyself\",\"date\":1353094689100}",sw.toString());
+ System.out.println(sw.toString());
+
+ // 10/01/2015 Jonathan AAF-703 Ron Gallagher, this response is ok
+ go(jin,jout, "{\"perm\":[{\"type\":\"org.osaaf.myns.myPerm\",\"action\":\"myAction\",\"description\":\"something\"}]}");
+ // but when description:"" causes extra comma at end
+ go(jin,jout, "{\"perm\":[{\"type\":\"org.osaaf.myns.myPerm\",\"action\":\"myAction\",\"description\":\"\"}]}","{\"perm\":[{\"type\":\"org.osaaf.myns.myPerm\",\"action\":\"myAction\"}]}");
+ // Test other empty string scenarios
+ go(jin,jout, "{\"perm\":[{\"type\":\"\",\"action\":\"\",\"description\":\"\"}]}","{\"perm\":[{}]}");
+ go(jin,jout, "{\"perm\":[{\"type\":\"\",\"action\":\"\",\"description\":\"hi\"}]}","{\"perm\":[{\"description\":\"hi\"}]}");
+ go(jin,jout, "{\"perm\":[{\"type\":\"\",\"action\":\"myAction\",\"description\":\"\"}]}","{\"perm\":[{\"action\":\"myAction\"}]}");
+
+
+ go(jin,jout, "{\"perm\":[{\"type\":\"org.osaaf.myns.myPerm\",\"action\":,\"description\":\"something\"}]}","{\"perm\":[{\"type\":\"org.osaaf.myns.myPerm\",\"description\":\"something\"}]}");
+
+ go(jin, jout, "{\"name\":\"\\\"hello\\\"\"}");
+
+ go(jin, jout, "{\"name\":\"\\\\\"}");
+
+ go(jin, jout, "{\"role\":\"org.osaaf.scamper.UserStory0152 7_IT-00323-a-admin\",\"perm\":{\"type\":\"org.osaaf.scamper.application\",\"instance\":\"_()`!@#\\\\$%^=+][{}<>/.-valid.app.name-is_good\",\"action\":\"Administrator\"}}");
+
+
+ }
+
+
+ private void go(Parse<Reader,?> in, Out out, String str) throws IOException, ParseException {
+ go(in,out,str,str);
+ }
+
+
+ private void go(Parse<Reader, ?> in, Out out, String str, String cmp) throws IOException, ParseException {
+
+ System.out.println(str);
+ StringWriter sw = new StringWriter(1024);
+ out.extract(new StringReader(str), sw, in);
+ System.out.println(sw);
+ String result = sw.toString();
+
+ if(!result.equals(cmp)) {
+ sw.getBuffer().setLength(0);
+ new OutRaw().extract(new StringReader(str), sw, in);
+ System.out.println(sw);
+ }
+
+ Assert.assertEquals(cmp,result);
+ System.out.println();
+
+ }
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Ladder.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Ladder.java
new file mode 100644
index 0000000..f72b6e6
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Ladder.java
@@ -0,0 +1,76 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import org.junit.Test;
+import org.onap.aaf.misc.rosetta.Ladder;
+
+import static org.junit.Assert.*;
+
+public class JU_Ladder {
+
+ @Test
+ public void test() {
+ Ladder<String> ladder = new Ladder<String>();
+
+ for(int i=0;i<30;++i) {
+ for(int j=0;j<i;++j)ladder.ascend();
+ String str = "Rung " + i;
+ assertEquals(ladder.peek(),null);
+ ladder.push(str);
+ assertEquals(str,ladder.peek());
+ assertEquals(str,ladder.pop());
+ assertEquals(null,ladder.peek());
+ for(int j=0;j<i;++j)ladder.descend();
+ }
+ assertEquals(ladder.height(),32); // Sizing, when naturally created is by 8
+
+ ladder.cutTo(8);
+ assertEquals(ladder.height(),8);
+
+ for(int i=0;i<30;++i) {
+ ladder.jumpTo(i);
+ String str = "Rung " + i;
+ assertEquals(ladder.peek(),null);
+ ladder.push(str);
+ assertEquals(ladder.peek(),str);
+ }
+
+ ladder.bottom();
+
+ for(int i=0;i<30;++i) {
+ assertEquals("Rung " + i,ladder.peek());
+ ladder.ascend();
+ }
+
+ ladder.bottom();
+ ladder.top();
+ assertEquals("Rung 29",ladder.peek());
+
+ for(int i=0;i<30;++i) {
+ ladder.jumpTo(i);
+ assertEquals("Rung " + i,ladder.peek());
+ }
+
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Nulls.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Nulls.java
new file mode 100644
index 0000000..cff5b43
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Nulls.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import junit.framework.Assert;
+
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.rosetta.env.RosettaDF;
+import org.onap.aaf.misc.rosetta.env.RosettaData;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+import s.xsd.LargerData;
+import s.xsd.SampleData;
+
+public class JU_Nulls {
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ @Test
+ public void test() {
+ RosettaEnv env = new RosettaEnv();
+ try {
+ RosettaDF<LargerData> df = env.newDataFactory(LargerData.class);
+ df.out(Data.TYPE.JSON);
+ LargerData urr = new LargerData();
+ SampleData sd = new SampleData();
+ sd.setDate(1444125487798L);
+ sd.setId(null);
+ urr.getSampleData().add(sd);
+ urr.setFluff(null);
+ RosettaData<LargerData> data = df.newData();
+// StringWriter sw = new StringWriter();
+// df.direct(trans, urr, sw);
+// System.out.println(sw.toString());
+ data.load(urr);
+ System.out.println(data.asString());
+ Assert.assertEquals("{\"SampleData\":[{\"date\":1444125487798}]}", data.asString());
+
+ System.out.println(data.out(Data.TYPE.RAW).asString());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_RosettaDF.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_RosettaDF.java
new file mode 100644
index 0000000..07c7319
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_RosettaDF.java
@@ -0,0 +1,162 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.StringReader;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Data.TYPE;
+import org.onap.aaf.misc.env.impl.EnvFactory;
+import org.onap.aaf.misc.env.jaxb.JAXBmar;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.rosetta.env.RosettaDF;
+import org.onap.aaf.misc.rosetta.env.RosettaData;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+import s.xsd.LargerData;
+import s.xsd.Multi;
+import s.xsd.SampleData;
+
+public class JU_RosettaDF {
+ public static int ITERATIONS = 1;
+
+ @Test
+ public void testCached() throws Exception {
+ RosettaEnv env = new RosettaEnv();
+ RosettaDF<LargerData> df = env.newDataFactory(LargerData.class);
+ JAXBmar jmar = new JAXBmar(LargerData.class);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+ Trans trans = EnvFactory.newTrans();
+
+ Report report = new Report(ITERATIONS,"Load JSON","Extract JAXB", "JAXB Marshal", "Cached to XML", "Cached to JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Data<LargerData> data;
+ TimeTaken tt = trans.start("Load JSON", 1);
+ try {
+ data = df.newData(trans).out(Data.TYPE.JSON).in(Data.TYPE.JSON).load(JU_FromJSON.str);
+ } finally {
+ tt.done();
+ }
+ LargerData ld;
+ tt = trans.start("Extract JAXB", 2);
+ try {
+ ld = data.asObject();
+ } finally {
+ tt.done();
+ }
+
+ tt = trans.start("JAXB marshal", 3);
+ try {
+ jmar.marshal(trans.debug(), ld, sbw);
+ } finally {
+ tt.done();
+ }
+ sbw.append('\n');
+
+ tt = trans.start("To XML from Cache",4);
+ try {
+ data.out(Data.TYPE.XML).to(sbw);
+ } finally {
+ tt.done();
+ }
+
+ sbw.append('\n');
+
+ tt = trans.start("To JSON from Cache",5);
+ try {
+ data.out(Data.TYPE.JSON).to(sbw);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans, 1,2,3,4,5);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw);
+
+ }
+
+ @Test
+ public void testDirect() throws Exception {
+ RosettaEnv env = new RosettaEnv();
+ RosettaDF<LargerData> df = env.newDataFactory(LargerData.class);
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+ Trans trans = EnvFactory.newTrans();
+
+ Report report = new Report(ITERATIONS);
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ RosettaData<?> data = df.newData(trans).in(Data.TYPE.JSON).out(Data.TYPE.XML);
+ data.direct(new StringReader(JU_FromJSON.str), sbw);
+ report.glean(trans);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw);
+
+ }
+
+ @Test
+ public void testMulti() throws Exception {
+ RosettaEnv env = new RosettaEnv();
+ RosettaDF<Multi> df = env.newDataFactory(Multi.class);
+
+// StringBuilderWriter sbw = new StringBuilderWriter(1024);
+// Trans trans = EnvFactory.newTrans();
+
+ Multi m = new Multi();
+ m.getF1().add("String1");
+ m.getF2().add("String2");
+
+ System.out.println(df.newData().load(m).out(TYPE.RAW).asString());
+ System.out.println(df.newData().load(m).out(TYPE.JSON).asString());
+
+ }
+
+ @Test
+ public void testQuotes() throws Exception {
+ RosettaEnv env = new RosettaEnv();
+ RosettaDF<SampleData> df = env.newDataFactory(SampleData.class);
+
+ SampleData sd = new SampleData();
+ sd.setId("\"AT&T Services, Inc.\"");
+ System.out.println(sd.getId());
+ String out =df.newData().load(sd).out(TYPE.JSON).asString();
+ System.out.println(out);
+ Assert.assertEquals(
+ "{\"id\":\"\\\"AT&T Services, Inc.\\\"\",\"date\":0}",
+ out);
+
+ SampleData sd2 = df.newData().in(TYPE.JSON).load(out).asObject();
+ System.out.println(sd2.getId());
+ Assert.assertEquals(sd.getId(),sd2.getId());
+ }
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Saved.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Saved.java
new file mode 100644
index 0000000..4795300
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Saved.java
@@ -0,0 +1,104 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.impl.EnvFactory;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.rosetta.InJson;
+import org.onap.aaf.misc.rosetta.JaxInfo;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutXML;
+import org.onap.aaf.misc.rosetta.Saved;
+
+import s.xsd.LargerData;
+
+public class JU_Saved<b> {
+ private static int ITERATIONS = 100000;
+
+ @Test
+ public void test() throws Exception {
+ InJson inJSON = new InJson();
+ OutDump dump = new OutDump();
+ JaxInfo ji = JaxInfo.build(LargerData.class);
+ OutXML xml = new OutXML(ji);;
+ OutJson json = new OutJson();
+
+ Saved saved = new Saved();
+
+ StringBuilderWriter sbw = new StringBuilderWriter(1024);
+
+ Trans trans;
+ Report report = new Report(ITERATIONS,"Save","Dump","XML ","JSON");
+ do {
+ sbw.reset();
+ trans = EnvFactory.newTrans();
+ Reader sr = new StringReader(JU_FromJSON.str);
+ TimeTaken tt = trans.start("Parse Text, and Save", 1);
+ try {
+ saved.load(sr, inJSON);
+ } finally {
+ tt.done();
+ }
+
+// sbw.append("==== Start Direct Raw =====\n");
+// new OutRaw().extract(new StringReader(JU_FromJSON.str), sbw, inJSON);
+//
+// sbw.append("==== Start Raw from Saved =====\n");
+// new OutRaw().extract(null,sbw,saved);
+
+ sbw.append("==== Start Dump from Saved =====\n");
+ tt = trans.start("Dump", 2);
+ try {
+ dump.extract(null,sbw,saved);
+ } finally {
+ tt.done();
+ }
+
+ sbw.append("\n==== Start XML =====\n");
+ tt = trans.start("XML", 3);
+ try {
+ xml.extract(null,sbw,saved);
+ } finally {
+ tt.done();
+ }
+
+ sbw.append("\n==== Start JSON =====\n");
+ tt = trans.start("JSON", 4);
+ try {
+ json.extract(null,sbw,saved);
+ } finally {
+ tt.done();
+ }
+ report.glean(trans,1,2,3,4);
+ } while(report.go());
+
+ report.report(sbw);
+ System.out.println(sbw.toString());
+
+ }
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Stream2Obj.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Stream2Obj.java
new file mode 100644
index 0000000..6047c03
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Stream2Obj.java
@@ -0,0 +1,123 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import inherit.DerivedA;
+import inherit.Root;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.DataFactory;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.impl.BasicEnv;
+import org.onap.aaf.misc.rosetta.InJson;
+import org.onap.aaf.misc.rosetta.InXML;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.OutXML;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.ParseException;
+
+public class JU_Stream2Obj {
+
+ /*
+ <?xml version="1.0" encoding=Config.UTF-8 standalone="yes"?>
+ <root xmlns="urn:inherit">
+ <base xsi:type="derivedA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <name>myDerivedA_1</name>
+ <num>1432</num>
+ <shortName>mda_1</shortName>
+ <value>value_1</value>
+ <value>value_2</value>
+ </base>
+ </root>
+
+ {"base":[{"__extension":"derivedA","name":"myDerivedA_1","num":1432,"shortName":"mda_1","value":["value_1","value_2"]}]}
+ */
+
+ @Test
+ public void json2Obj() throws APIException, SecurityException, NoSuchFieldException, ClassNotFoundException, ParseException, IOException {
+ DerivedA da = new DerivedA();
+ da.setName("myDerivedA_1");
+ da.setNum((short)1432);
+ da.setShortName("mda_1");
+ da.getValue().add("value_1");
+ da.getValue().add("value_2");
+
+ Root root = new Root();
+ root.getBase().add(da);
+
+ da = new DerivedA();
+ da.setName("myDerivedA_2");
+ da.setNum((short)1432);
+ da.setShortName("mda_2");
+ da.getValue().add("value_2.1");
+ da.getValue().add("value_2.2");
+ root.getBase().add(da);
+
+ EnvJAXB env = new BasicEnv();
+ DataFactory<Root> rootDF = env.newDataFactory(Root.class);
+
+ String xml = rootDF.newData(env).out(Data.TYPE.XML).load(root).option(Data.PRETTY).asString();
+ System.out.println(xml);
+
+ InXML inXML;
+ Parse<Reader,?> in = inXML = new InXML(Root.class);
+ Out out = new OutRaw();
+
+ StringWriter sw = new StringWriter();
+ out.extract(new StringReader(xml), sw, in);
+ System.out.println(sw.toString());
+
+
+ out = new OutJson();
+
+ sw = new StringWriter();
+ out.extract(new StringReader(xml), sw, in);
+ String json;
+ System.out.println(json = sw.toString());
+
+ in = new InJson();
+ out = new OutRaw();
+
+ sw = new StringWriter();
+ out.extract(new StringReader(json), sw, in);
+ System.out.println(sw.toString());
+
+ out = new OutXML(inXML);
+
+ sw = new StringWriter();
+ out.extract(new StringReader(json), sw, in, true);
+ System.out.println(sw.toString());
+
+ System.out.flush();
+
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Struct.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Struct.java
new file mode 100644
index 0000000..1209e77
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Struct.java
@@ -0,0 +1,73 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import org.junit.Test;
+import org.onap.aaf.misc.rosetta.JaxInfo;
+
+import s.xsd.LargerData;
+
+public class JU_Struct {
+ public final static String XML ="<LargerData xmlns=\"urn:s:xsd\">\n" +
+ "<SampleData>\n" +
+ "<id>sd object 1</id>\n" +
+ "<date>1346439215932</date>\n" +
+ "<item>Item 1.1</item>\n" +
+ "<item>Item 1.2</item>\n" +
+ "</SampleData>\n" +
+ "<SampleData>\n" +
+ "<id>sd object 2</id>\n" +
+ "<date>1346439215932</date>\n" +
+ "<item>Item 2.1</item>\n" +
+ "<item>Item 2.2</item>\n" +
+ "</SampleData>\n" +
+ "<fluff>MyFluff</fluff>\n" +
+ "</LargerData>\n";
+
+// @Test
+// public void test2() throws Exception {
+//
+// SampleData sd = new SampleData();
+// sd.setDate(new Date().getTime());
+// sd.setId("myId");
+// sd.getItem().add("Item 1.1");
+//
+// InObj<SampleData> inObj = new InObj<SampleData>(SampleData.class);
+//
+// JaxSet<SampleData> jaxSet = JaxSet.get(SampleData.class);
+// Setter<SampleData> setter = jaxSet.setter("id");
+// setter.set(sd, "Your ID");
+//
+// for(Entry<String, Getter<SampleData>> es : jaxSet.getters()) {
+// System.out.print(es.getKey());
+// System.out.print(' ');
+// System.out.println(es.getValue().get(sd));
+// }
+// }
+
+ @Test
+ public void test() throws Exception {
+ JaxInfo ji = JaxInfo.build(LargerData.class);
+ System.out.println(ji);
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Types.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Types.java
new file mode 100644
index 0000000..5d76e3c
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/JU_Types.java
@@ -0,0 +1,301 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.StringWriter;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Data.TYPE;
+import org.onap.aaf.misc.env.Trans.Metric;
+import org.onap.aaf.misc.env.jaxb.JAXBmar;
+import org.onap.aaf.misc.env.jaxb.JAXBumar;
+import org.onap.aaf.misc.env.util.Chrono;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.rosetta.OutJson;
+import org.onap.aaf.misc.rosetta.OutRaw;
+import org.onap.aaf.misc.rosetta.OutXML;
+import org.onap.aaf.misc.rosetta.env.RosettaDF;
+import org.onap.aaf.misc.rosetta.env.RosettaData;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+import org.onap.aaf.misc.rosetta.marshal.DocMarshal;
+import org.onap.aaf.misc.rosetta.test.obj.MultiMarshal;
+import org.onap.aaf.misc.rosetta.test.obj.SingleMarshal;
+
+import types.xsd.Multi;
+import types.xsd.Multi.Single;
+
+public class JU_Types {
+
+ @Test
+ public void single() throws Exception {
+ Single single = setSData();
+ SingleMarshal psingle = new SingleMarshal();
+
+ OutRaw raw = new OutRaw();
+ OutJson json = new OutJson();
+ OutXML xml = new OutXML("Single","xmlns=urn:types:xsd");
+
+
+ System.out.println("===== RAW =====");
+ raw.extract(single, System.out, psingle);
+
+ System.out.println("\n===== JSON =====");
+ json.extract(single, System.out, psingle);
+
+ System.out.println("\n\n===== Pretty JSON =====");
+ json.extract(single, System.out, psingle, true);
+
+ System.out.println("\n\n===== XML =====");
+ xml.extract(single, System.out, psingle,false);
+
+ System.out.println("\n\n===== Pretty XML =====");
+ xml.extract(single, System.out, psingle, true);
+
+ RosettaEnv env = new RosettaEnv();
+ StringWriter sw = new StringWriter();
+ xml.extract(single, sw, psingle, true);
+ JAXBumar jumar = new JAXBumar(single.getClass());
+ JAXBmar jmar = new JAXBmar(new QName("Single","urn.types.xsd"),single.getClass());
+ jmar.pretty(true);
+ sw = new StringWriter();
+ jmar.marshal(env.info(), single, sw);
+ System.out.println(sw);
+ Single news = jumar.unmarshal(env.info(), sw.toString());
+// System.out.println(news.getDatetime());
+// sw = new StringWriter();
+// news.setDatetime(Chrono.timeStamp());
+// xml.extract(single, sw, psingle, true);
+ news = jumar.unmarshal(env.info(), sw.toString());
+ System.out.println(sw.toString());
+
+ String sample = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ + "\n<ns2:urn.types.xsd xmlns:ns2=\"Single\" xmlns=\"urn:types:xsd\">"
+ + "\n<str>MyString</str>"
+ + "\n<int>2147483647</int>"
+ + "\n<long>9223372036854775807</long>"
+ + "\n<date>2015-05-27-05:00</date>"
+ + "\n<datetime>2015-05-27T07:05:04.234-05:00</datetime>"
+ + "\n<binary>FF00FF0E082507807F</binary>"
+ + "\n<array>String 1</array>"
+ + "\n<array>String 2</array>"
+ + "\n</ns2:urn.types.xsd>";
+ System.out.println(sample);
+ news = jumar.unmarshal(env.info(), sample);
+
+ System.out.println(news.getDatetime());
+
+ }
+
+ @Test
+ public void multi() throws Exception {
+ OutRaw raw = new OutRaw();
+ OutJson json = new OutJson();
+ OutXML xml = new OutXML("Multi","xmlns=urn:types:xsd");
+
+ Multi multi = new Multi();
+ MultiMarshal pmulti = new MultiMarshal();
+
+ for(int i=0;i<10;++i) {
+ System.out.println("===== Multi Iteration " + i + " =====");
+ if(i>0) {
+ multi.getSingle().add(setSData());
+ }
+ System.out.println(" ===== RAW =====");
+ raw.extract(multi, System.out, pmulti);
+
+ System.out.println("\n ===== JSON =====");
+ json.extract(multi, System.out, pmulti);
+
+ System.out.println("\n\n ===== Pretty JSON =====");
+ json.extract(multi, System.out, pmulti, true);
+
+ System.out.println("\n\n ===== XML =====");
+ xml.extract(multi, System.out, pmulti,false);
+
+ System.out.println("\n\n ===== Pretty XML =====");
+ xml.extract(multi, System.out, pmulti, true);
+ }
+ }
+
+ @Test
+ public void doc() throws Exception {
+ OutRaw raw = new OutRaw();
+ OutJson json = new OutJson();
+ OutXML xml = new OutXML("Multi","xmlns=urn:types:xsd");
+
+ Multi multi = new Multi();
+ DocMarshal<Multi> doc = DocMarshal.root(new MultiMarshal());
+
+ for(int i=0;i<3;++i) {
+ System.out.println("===== Multi Iteration " + i + " =====");
+ if(i>0) {
+ multi.getSingle().add(setSData());
+ }
+ System.out.println(" ===== RAW =====");
+ raw.extract(multi, System.out, doc);
+
+ System.out.println("\n ===== JSON =====");
+ json.extract(multi, System.out, doc);
+
+ System.out.println("\n\n ===== Pretty JSON =====");
+ json.extract(multi, System.out, doc, true);
+
+ System.out.println("\n\n ===== XML =====");
+ xml.extract(multi, System.out, doc,false);
+
+ System.out.println("\n\n ===== Pretty XML =====");
+ xml.extract(multi, System.out, doc, true);
+ }
+ }
+
+
+// @Test
+// public void saved() throws Exception {
+// Saved saved = new Saved();
+// saved.extract(in, ignore, parser, options);
+// }
+
+ @Test
+ public void df() throws Exception {
+ RosettaEnv env = new RosettaEnv();
+ RosettaDF<Multi> df = env.newDataFactory(Multi.class);
+ df.out(TYPE.JSON).option(Data.PRETTY);
+
+ Multi multi = new Multi();
+ multi.getSingle().add(setSData());
+
+
+ System.out.println("========== Original loading");
+ Trans trans = env.newTrans();
+ RosettaData<Multi> data = df.newData(trans);
+ // Prime pump
+ for(int i=0;i<100;++i) {
+ data.load(multi);
+ }
+ trans = env.newTrans();
+ data = df.newData(trans);
+
+ int iters = 10000;
+ for(int i=0;i<iters;++i) {
+ data.load(multi);
+ }
+ Metric metrics = trans.auditTrail(0, null,Env.JSON,Env.XML);
+ System.out.println(data.asString());
+ System.out.println(metrics.total/iters + "ms avg");
+
+ System.out.println("========== New loading");
+ // With new
+ df.rootMarshal(DocMarshal.root(new MultiMarshal()));
+ trans = env.newTrans();
+ data = df.newData(trans);
+
+ // Prime pump
+ for(int i=0;i<100;++i) {
+ data.load(multi);
+ }
+ trans = env.newTrans();
+ data = df.newData(trans);
+
+ for(int i=0;i<iters;++i) {
+ data.load(multi);
+ }
+ metrics = trans.auditTrail(0, null,Env.JSON,Env.XML);
+ System.out.println(data.asString());
+ System.out.println(metrics.total/iters + "ms avg");
+
+ // Assert.assertEquals(first, second);
+
+ System.out.println("========== Direct Object to JSON String");
+ trans = env.newTrans();
+ data = df.newData(trans);
+ StringBuilderWriter sbw = new StringBuilderWriter(256);
+ // Prime pump
+ for(int i=0;i<100;++i) {
+ sbw.reset();
+ data.direct(multi, sbw, true);
+ }
+ trans = env.newTrans();
+ data = df.newData(trans);
+
+ for(int i=0;i<iters;++i) {
+ sbw.reset();
+ data.direct(multi, sbw, true);
+ }
+
+ metrics = trans.auditTrail(0, null,Env.JSON,Env.XML);
+ System.out.println(sbw.toString());
+ System.out.println(metrics.total/iters + "ms avg");
+
+ }
+
+ private Single setSData() {
+ Single s = new Single();
+ s.setStr("MyString");
+ s.setInt(Integer.MAX_VALUE);
+ s.setLong(Long.MAX_VALUE);
+ XMLGregorianCalendar ts = Chrono.timeStamp();
+ s.setDate(ts);
+ s.setDatetime(ts);
+ byte[] bytes= new byte[] {-1,0,(byte)0XFF,0xE,0x8,0x25,0x7,Byte.MIN_VALUE,Byte.MAX_VALUE};
+ s.setBinary(bytes);
+ s.getArray().add("String 1");
+ s.getArray().add("String 2");
+ return s;
+ }
+
+// @Test
+// public void jsonInOut() throws IOException, ParseException {
+// Parse<?> jin = new InJson();
+// Out jout = new OutJson();
+//
+//// go(jin, jout, "{\"id\":\"Me, Myself\",\"date\":1353094689100}");
+//
+// }
+
+
+ /*
+ private void go(Parse<Reader,?> in, Out out, String str) throws IOException, ParseException {
+
+ System.out.println(str);
+ StringWriter sw = new StringWriter(1024);
+ out.extract(new StringReader(str), sw, in);
+ System.out.println(sw);
+ String result = sw.toString();
+
+ if(!result.equals(str)) {
+ sw.getBuffer().setLength(0);
+ new OutRaw().extract(new StringReader(str), sw, in);
+ System.out.println(sw);
+ }
+
+ Assert.assertEquals(str,result);
+ System.out.println();
+
+ }
+ */
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/OutDump.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/OutDump.java
new file mode 100644
index 0000000..ab0c921
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/OutDump.java
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+import org.onap.aaf.misc.rosetta.Out;
+import org.onap.aaf.misc.rosetta.Parse;
+import org.onap.aaf.misc.rosetta.ParseException;
+import org.onap.aaf.misc.rosetta.Parsed;
+
+public class OutDump extends Out{
+
+ @Override
+ public<IN, S> void extract(IN in, Writer writer, Parse<IN,S> prs, boolean ... options) throws IOException, ParseException {
+ IndentPrintWriter ipw = writer instanceof IndentPrintWriter?(IndentPrintWriter)writer:new IndentPrintWriter(writer);
+
+ Parsed<S> p = prs.newParsed();
+
+ while((p = prs.parse(in,p.reuse())).valid()) {
+ switch(p.event) {
+ case Parse.START_OBJ:
+ ipw.append("Start Object ");
+ ipw.append(p.name);
+ ipw.inc();
+ break;
+ case Parse.END_OBJ:
+ printData(ipw,p);
+ ipw.dec();
+ ipw.append("End Object ");
+ ipw.append(p.name);
+ break;
+ case Parse.START_ARRAY:
+ ipw.inc();
+ ipw.append("Start Array ");
+ ipw.append(p.name);
+ ipw.append('\n');
+ break;
+ case Parse.END_ARRAY:
+ printData(ipw,p);
+ ipw.dec();
+ ipw.append("End Array ");
+ ipw.append('\n');
+ break;
+ case Parse.NEXT:
+ printData(ipw,p);
+ break;
+ }
+ }
+ }
+
+ private void printData(IndentPrintWriter ipw, Parsed<?> parsed) {
+ if(parsed.hasData()) {
+ ipw.append("Data:[");
+ if(parsed.hasName()) {
+ ipw.append(parsed.name);
+ ipw.append(" : ");
+ }
+ ipw.append(parsed.sb);
+ ipw.append("]");
+ ipw.append('\n');
+ }
+ }
+
+ @Override
+ public String logName() {
+ return "Rosetta OutDump";
+ }
+
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/Report.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/Report.java
new file mode 100644
index 0000000..5c709ad
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/Report.java
@@ -0,0 +1,67 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Trans.Metric;
+
+public class Report {
+ float total;
+ float buckets[];
+ String[] names;
+ private int iterations;
+ private int count;
+
+ public Report(int iters, String ... names) {
+ iterations = iters;
+ buckets = new float[names.length];
+ this.names = names;
+ total=0;
+ count = 0;
+ }
+
+ public void glean(Trans trans, int ... type) {
+ Metric m = trans.auditTrail(0, null, type);
+ total+=m.total;
+ int min = Math.min(buckets.length, m.buckets.length);
+ for(int b=0;b<min;++b) {
+ buckets[b]+=m.buckets[b];
+ }
+ }
+
+ public boolean go() {
+ return ++count<iterations;
+ }
+
+
+ public void report(Writer sbw) throws IOException {
+ sbw.append("\n"+count + " entries, Total Time: " + total + "ms, Avg Time: " + total/count + "ms\n");
+ int min = Math.min(buckets.length, names.length);
+ for(int i=0;i<min;++i) {
+ sbw.append(" Time: " + names[i] + ' ' + buckets[i] + "ms, Avg Time: " + buckets[i]/count + "ms\n");
+ }
+
+ }
+}
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/MultiMarshal.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/MultiMarshal.java
new file mode 100644
index 0000000..5e96a37
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/MultiMarshal.java
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test.obj;
+
+import java.util.List;
+
+import org.onap.aaf.misc.rosetta.marshal.ObjArray;
+import org.onap.aaf.misc.rosetta.marshal.ObjMarshal;
+
+import types.xsd.Multi;
+import types.xsd.Multi.Single;
+
+public class MultiMarshal extends ObjMarshal<Multi> {
+ public MultiMarshal() {
+ add(new ObjArray<Multi,Single>("single",new SingleMarshal()) {
+ @Override
+ protected List<Single> data(Multi t) {
+ return t.getSingle();
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/SingleMarshal.java b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/SingleMarshal.java
new file mode 100644
index 0000000..932277d
--- /dev/null
+++ b/misc/rosetta/src/test/java/org/onap/aaf/misc/rosetta/test/obj/SingleMarshal.java
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.rosetta.test.obj;
+
+import java.util.List;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.onap.aaf.misc.rosetta.marshal.DataWriter;
+import org.onap.aaf.misc.rosetta.marshal.FieldArray;
+import org.onap.aaf.misc.rosetta.marshal.FieldDate;
+import org.onap.aaf.misc.rosetta.marshal.FieldDateTime;
+import org.onap.aaf.misc.rosetta.marshal.FieldHexBinary;
+import org.onap.aaf.misc.rosetta.marshal.FieldNumeric;
+import org.onap.aaf.misc.rosetta.marshal.FieldString;
+import org.onap.aaf.misc.rosetta.marshal.ObjMarshal;
+
+import types.xsd.Multi.Single;
+
+public class SingleMarshal extends ObjMarshal<Single> {
+ public SingleMarshal() {
+ add(new FieldString<Single>("str") {
+ @Override
+ protected String data(Single t) {
+ return t.getStr();
+ }
+ });
+
+ add(new FieldNumeric<Integer, Single>("int") {
+ @Override
+ protected Integer data(Single t) {
+ return t.getInt();
+ }
+ });
+
+ add(new FieldNumeric<Long,Single>("long") {
+ @Override
+ protected Long data(Single t) {
+ return t.getLong();
+ }
+ });
+
+ add(new FieldDate<Single>("date") {
+ @Override
+ protected XMLGregorianCalendar data(Single t) {
+ return t.getDate();
+ }
+ });
+
+ add(new FieldDateTime<Single>("datetime") {
+ @Override
+ protected XMLGregorianCalendar data(Single t) {
+ return t.getDate();
+ }
+ });
+
+ add(new FieldHexBinary<Single>("binary") {
+ @Override
+ protected byte[] data(Single t) {
+ return t.getBinary();
+ }
+ });
+
+ add(new FieldArray<Single,String>("array", DataWriter.STRING) {
+ @Override
+ protected List<String> data(Single t) {
+ return t.getArray();
+ }
+ });
+
+ }
+}
\ No newline at end of file
diff --git a/misc/xgen/.gitignore b/misc/xgen/.gitignore
new file mode 100644
index 0000000..75472cf
--- /dev/null
+++ b/misc/xgen/.gitignore
@@ -0,0 +1,4 @@
+/target/
+/.classpath
+/.settings/
+/.project
diff --git a/misc/xgen/pom.xml b/misc/xgen/pom.xml
new file mode 100644
index 0000000..982920a
--- /dev/null
+++ b/misc/xgen/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aaf-misc-xgen</artifactId>
+ <name>AAF Misc XGen</name>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>aaf-misc-env</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <!-- <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId> <version>2.6</version> <configuration>
+ <skip>false</skip> </configuration> </plugin> </plugins> </build> <distributionManagement>
+ <repository> <id>nexus</id> <name>attarch-releases</name> <url>http://mavencentral.it.att.com:8084/nexus/content/repositories/attarch-releases</url>
+ </repository> <snapshotRepository> <id>nexus</id> <name>attarch-snapshots</name>
+ <url>http://mavencentral.it.att.com:8084/nexus/content/repositories/attarch-snapshots</url>
+ </snapshotRepository> </distributionManagement> -->
+</project>
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Back.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Back.java
new file mode 100644
index 0000000..71c10aa
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Back.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+public class Back {
+ public String str;
+ public boolean dec;
+ public boolean cr;
+
+ public Back(String string, boolean decrement, boolean newline) {
+ str = string;
+ dec = decrement;
+ cr = newline;
+ }
+}
\ No newline at end of file
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Cache.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Cache.java
new file mode 100644
index 0000000..2a9ee67
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Cache.java
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+
+public interface Cache<G extends XGen<G>> {
+ public void dynamic(G hgen, Code<G> code);
+
+ public static class Null<N extends XGen<N>> implements Cache<N> {
+ @Override
+ public void dynamic(N hgen, Code<N> code) {} // NO_OP, no matter what type
+
+ @SuppressWarnings("rawtypes")
+ private static Null<?> singleton = new Null();
+ public static Null<?> singleton() { return singleton;}
+ }
+
+}
\ No newline at end of file
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/CacheGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/CacheGen.java
new file mode 100644
index 0000000..aa3d1fe
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/CacheGen.java
@@ -0,0 +1,131 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.xgen.html.State;
+import org.onap.aaf.misc.xgen.html.Thematic;
+
+
+public abstract class CacheGen<G extends XGen<G>> {
+ public static final int NO_FLAGS = 0x0;
+ public final static int PRETTY = 0x1;
+ public final static int XML = 0x2;
+ public final static int HTML4 = 0x4;
+ public final static int HTML5 = 0x8;
+
+
+ private ArrayList<Section<G>> sections = new ArrayList<Section<G>>();
+ private int flags;
+ private final Thematic thematic;
+
+ public CacheGen(int flags, Code<G> code) throws APIException, IOException {
+ this.flags = flags;
+ final XGenBuff<G> buff = new XGenBuff<G>(flags,this);
+ // Run to gather Strings and Code Class Segments
+ buff.run(new Cache<G>() {
+ @Override
+ public void dynamic(G hgen, Code<G> code) {
+ sections.add(buff.newSection());
+ sections.add(new Dynamic(hgen.getIndent(),code));
+ }
+ },code);
+ sections.add(buff.newSection());
+
+ // If Code implements thematic, set for later
+ thematic = code instanceof Thematic?(Thematic)code:null;
+
+ }
+
+ public abstract G create(int htmlStyle, Writer w);
+
+ public void replay(State<Env> state, Trans trans, OutputStream os, String theme) throws IOException, APIException {
+ replay(state, trans, new OutputStreamWriter(os), theme);
+ }
+
+ public void replay(State<Env> state, Trans trans,Writer w, String theme) throws IOException, APIException {
+ if(thematic!=null) {
+ theme = thematic.themeResolve(theme);
+ }
+ /* Theme
+ trans.setTheme(theme);
+ int htmlStyle = state.htmlVer(theme);
+ */
+
+ XGenBuff<G> buff = new XGenBuff<G>(flags,this);
+
+ // forward
+ int indent = 0;
+ Section<G> s;
+ int i=0;
+ @SuppressWarnings("unchecked")
+ Section<G>[] reverse = new Section[sections.size()];
+ for(Section<G> section : sections) {
+ s = section.use(state, trans, buff); // note, doesn't change cached, only dynamic, which is created for thread
+ int tempIndent = s.getIndent();
+ s.setIndent(indent);
+ s.forward(w);
+ s.setIndent(tempIndent);
+ indent = tempIndent;
+ reverse[i++]=s;
+ }
+
+ for(--i;i>=0;--i) {
+ reverse[i].back(w);
+ }
+ w.flush();
+ }
+
+ private class Dynamic extends Section<G> {
+ private Code<G> code;
+
+ public Dynamic(int indent, Code<G> code) {
+ this.code = code;
+ this.indent = indent;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Section<G> use(State<Env> state, Trans trans, XGenBuff<G> buff) throws APIException, IOException {
+ // Clone Dynamic to make Thread Safe
+ Dynamic d = new Dynamic(indent,code);
+ buff.setIndent(indent);
+ if(code instanceof DynamicCode) {
+ buff.run(state,trans,Cache.Null.singleton(), (DynamicCode<G,?,? extends Trans>)code);
+ } else {
+ buff.run((Cache<G>)Cache.Null.singleton(), code);
+ }
+ Section<G> s = buff.newSection();
+ d.indent = s.indent;
+ d.forward = s.forward;
+ d.backward = s.backward;
+ return d;
+ }
+ }
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Code.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Code.java
new file mode 100644
index 0000000..96418df
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Code.java
@@ -0,0 +1,30 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.IOException;
+
+import org.onap.aaf.misc.env.APIException;
+
+public interface Code<G extends XGen<G>> {
+ public void code(Cache<G> cache, G xgen) throws APIException, IOException;
+}
\ No newline at end of file
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/DynamicCode.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/DynamicCode.java
new file mode 100644
index 0000000..1b798fb
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/DynamicCode.java
@@ -0,0 +1,44 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.IOException;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.xgen.html.State;
+
+/**
+ * Special Code Interface to gain access to Transaction
+ * and State information
+ * @author Jonathan
+ *
+ */
+public abstract class DynamicCode<G extends XGen<G>, AS extends State<Env>, TRANS extends Trans> implements Code<G> {
+ public abstract void code(final AS state, final TRANS trans, final Cache<G> cache, final G xgen) throws APIException, IOException;
+
+ // We expect not to have this section of the code engaged at any time
+ public void code(final Cache<G> cache, final G xgen) throws APIException, IOException {
+ code(null, null,cache,xgen);
+ }
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Mark.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Mark.java
new file mode 100644
index 0000000..92dc5b9
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Mark.java
@@ -0,0 +1,40 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+public class Mark {
+ // package on purpose
+ int spot = 0;
+ public String comment;
+
+ public Mark() {
+ comment = null;
+ }
+
+ public Mark(String string) {
+ comment = string;
+ }
+
+ public void spot(int spot) {
+ this.spot = spot;
+ }
+}
\ No newline at end of file
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java
new file mode 100644
index 0000000..8eb98ff
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/Section.java
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.xgen.html.State;
+
+public class Section<G extends XGen<G>> {
+ protected int indent;
+ protected String forward;
+ protected String backward;
+
+ // Default is to use the set Strings (static)
+ public Section<G> use(State<Env> state, Trans trans, XGenBuff<G> buff) throws APIException, IOException {
+ return this;
+ }
+
+ public int getIndent() {
+ return indent;
+ }
+
+ public void setIndent(int indent) {
+ this.indent = indent;
+ }
+
+ public void forward(Writer w) throws IOException {
+ w.write(forward);
+ }
+
+ public void back(Writer w) throws IOException {
+ w.write(backward);
+ }
+
+ public String toString() {
+ return forward;
+ }
+}
\ No newline at end of file
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGen.java
new file mode 100644
index 0000000..09c0311
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGen.java
@@ -0,0 +1,296 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.Stack;
+
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+
+public class XGen<RT extends XGen<RT>> {
+
+ public static int COMMENT_COLUMN = 40;
+ private StringBuilder backSB = new StringBuilder();
+ private Stack<Back> backStack = new Stack<Back>();
+
+ protected XGen(Writer w) {
+ forward = new IndentPrintWriter(w);
+ }
+
+ public int pushBack(Back b) {
+ int rv = backStack.size();
+ backStack.push(b);
+ return rv;
+ }
+
+ public boolean pretty = false;
+ protected IndentPrintWriter forward;
+
+ public IndentPrintWriter getWriter() {
+ return forward;
+ }
+
+ protected PrintWriter back = new PrintWriter(
+ new StringBuilderWriter(backSB));
+
+ @SuppressWarnings("unchecked")
+ public RT pretty() {
+ pretty = true;
+ return (RT) this;
+ }
+
+ protected void prettyln(PrintWriter pw) {
+ if(pretty)pw.println();
+ }
+
+ public RT leaf(Mark mark, String tag, String ... args) {
+ mark.spot = backStack.size();
+ return leaf(tag, args);
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT leaf(String tag, String ... attrs) {
+ forward.append('<');
+ forward.append(tag);
+ addAttrs(attrs);
+ forward.append('>');
+ back.append("</");
+ back.append(tag);
+ back.append('>');
+ backStack.push(new Back(backSB.toString(), false, true));
+ backSB.setLength(0);
+ return (RT)this;
+ }
+
+ public RT incr(String tag, String ... args) {
+ return incr(null, tag, false, args);
+ }
+
+ public RT incr(String tag, boolean oneLine, String ... args) {
+ return incr(null, tag, oneLine, args);
+ }
+
+ public RT incr(Mark mark) {
+ return incr(mark,mark.comment, false, new String[0]);
+ }
+
+ public RT incr(Mark mark, String tag, String ... attrs) {
+ return incr(mark, tag, false, attrs);
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT incr(Mark mark, String tag, boolean oneLine, String ... attrs) {
+ forward.append('<');
+ forward.append(tag);
+ addAttrs(attrs);
+ forward.append('>');
+
+ back.append("</");
+ back.append(tag);
+ back.append('>');
+
+ if(pretty) {
+ if(mark!=null && mark.comment!=null) {
+ int fi = forward.getIndent()*IndentPrintWriter.INDENT;
+ for(int i = fi+backSB.length();i<=COMMENT_COLUMN;++i) {
+ back.append(' ');
+ }
+ back.append("<!-- end ");
+ back.append(mark.comment);
+ back.append(" -->");
+
+ forward.toCol(COMMENT_COLUMN);
+ forward.append("<!-- begin ");
+ forward.append(mark.comment);
+ forward.append(" -->");
+ }
+ forward.inc();
+ if(!oneLine) {
+ forward.println();
+ }
+ back.println();
+ }
+ if(mark!=null)mark.spot = backStack.size();
+ backStack.push(new Back(backSB.toString(),true, false));
+ backSB.setLength(0);
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT tagOnly(String tag, String ... attrs) {
+ forward.append('<');
+ forward.append(tag);
+ addAttrs(attrs);
+ forward.append(" />");
+ if(pretty) {
+ forward.println();
+ }
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT text(String txt) {
+ forward.append(txt);
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT xml(String txt) {
+ for(int i=0; i<txt.length();++i) {
+ char c = txt.charAt(i);
+ switch(c) {
+ case '<':
+ forward.append("<");
+ break;
+ case '>':
+ forward.append(">");
+ break;
+ case '&':
+ forward.append("&");
+ break;
+ default:
+ forward.append(c);
+ }
+ }
+ return (RT)this;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public RT textCR(int tabs, String txt) {
+ for(int i=0;i<tabs;++i) {
+ forward.append(" ");
+ }
+ forward.append(txt);
+ if(pretty)forward.println();
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT value() {
+ Mark mark = new Mark();
+ mark.spot = backStack.size()-1;
+ end(mark);
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT value(String txt) {
+ forward.append(txt);
+ Mark mark = new Mark();
+ mark.spot = backStack.size()-1;
+ end(mark);
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT value(String txt, int levels) {
+ forward.append(txt);
+ Mark mark = new Mark();
+ mark.spot = backStack.size()-levels;
+ end(mark);
+ return (RT)this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT end(Mark mark) {
+ int size = backStack.size();
+ Back c;
+ boolean println = false;
+ for(int i=mark==null?0:mark.spot;i<size;++i) {
+ c = backStack.pop();
+ if(c.dec)forward.dec();
+ forward.append(c.str);
+ println = c.cr;
+ }
+ if(pretty && println) {
+ forward.println();
+ }
+ return (RT)this;
+ }
+
+ public RT end() {
+ Mark mark = new Mark();
+ mark.spot=backStack.size()-1;
+ if(mark.spot<0)mark.spot=0;
+ return end(mark);
+ }
+
+ public RT end(int i) {
+ Mark mark = new Mark();
+ mark.spot=backStack.size()-i;
+ if(mark.spot<0)mark.spot=0;
+ return end(mark);
+ }
+
+ public void endAll() {
+ end(new Mark());
+ forward.flush();
+ }
+
+ protected void addAttrs(String[] attrs) {
+ if(attrs!=null) {
+ for(String attr : attrs) {
+ if(attr!=null && attr.length()>0) {
+ forward.append(' ');
+ String[] split = attr.split("=",2);
+ switch(split.length) {
+ case 0:
+ break;
+ case 1:
+ forward.append(split[0]);
+// forward.append("=\"\"");
+ break;
+ default:
+ forward.append(split[0]);
+ forward.append("=\"");
+ forward.append(split[1]);
+ forward.append('"');
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public RT comment(String string) {
+ if(pretty) {
+ forward.print("<!-- ");
+ forward.print(string);
+ forward.println(" -->");
+ }
+ return (RT)this;
+ }
+
+ public void setIndent(int indent) {
+ forward.setIndent(indent);
+ forward.toIndent();
+ }
+
+ public int getIndent() {
+ return forward.getIndent();
+ }
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGenBuff.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGenBuff.java
new file mode 100644
index 0000000..95c4060
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/XGenBuff.java
@@ -0,0 +1,86 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen;
+
+import java.io.IOException;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.util.StringBuilderWriter;
+import org.onap.aaf.misc.xgen.html.State;
+
+public class XGenBuff<G extends XGen<G>> {
+ private G xgen;
+ private StringBuilder sb;
+ // private String forward, backward;
+
+ public XGenBuff(int flags, CacheGen<G> cg) {
+ sb = new StringBuilder();
+ xgen = cg.create(flags, new StringBuilderWriter(sb));
+ }
+
+ /**
+ * Normal case of building up Cached HTML without transaction info
+ *
+ * @param cache
+ * @param code
+ * @throws APIException
+ * @throws IOException
+ */
+ public void run(Cache<G> cache, Code<G> code) throws APIException, IOException {
+ code.code(cache, xgen);
+ }
+
+ /**
+ * Special Case where code is dynamic, so give access to State and Trans info
+ *
+ * @param state
+ * @param trans
+ * @param cache
+ * @param code
+ * @throws APIException
+ * @throws IOException
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void run(State<Env> state, Trans trans, Cache cache, DynamicCode code) throws APIException, IOException {
+ code.code(state, trans, cache, xgen);
+ }
+
+ public int getIndent() {
+ return xgen.getIndent();
+ }
+
+ public void setIndent(int indent) {
+ xgen.setIndent(indent);
+ }
+
+ public Section<G> newSection() {
+ Section<G> s = new Section<G>();
+ s.indent = xgen.getIndent();
+ s.forward = sb.toString();
+ sb.setLength(0);
+ s.backward = sb.toString();
+ sb.setLength(0);
+ return s;
+ }
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML4Gen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML4Gen.java
new file mode 100644
index 0000000..dfab12c
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML4Gen.java
@@ -0,0 +1,143 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.io.Writer;
+
+import org.onap.aaf.misc.xgen.Mark;
+
+public class HTML4Gen extends HTMLGen {
+ private final static String DOCTYPE =
+ /*
+ "<!DOCTYPE HTML PUBLIC " +
+ "\"-//W3C//DTD HTML 4.01 Transitional//EN\" " +
+ "\"http://www.w3.org/TR/html3/loose.dtd\">";
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" +
+ " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
+ */
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
+ " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
+
+ public HTML4Gen(Writer w) {
+ super(w);
+ }
+
+ @Override
+ public HTMLGen html(String ... attrib) {
+ forward.println(DOCTYPE);
+ return incr("html","xmlns=http://www.w3.org/1999/xhtml","xml:lang=en","lang=en");
+
+ }
+
+ @Override
+ public Mark head() {
+ Mark head = new Mark("head");
+ incr(head);
+ return head;
+ }
+
+ @Override
+ public Mark body(String ... attrs) {
+ Mark body = new Mark("body");
+ incr(body,"body",attrs);
+ return body;
+ }
+
+ @Override
+ public HTML4Gen charset(String charset) {
+ forward.append("<meta http-equiv=\"Content-type\" content=\"text.hml; charset=");
+ forward.append(charset);
+ forward.append("\">");
+ prettyln(forward);
+ return this;
+ }
+
+ @Override
+ public Mark header(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="header";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+ @Override
+ public Mark footer(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="footer";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+ @Override
+ public Mark section(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="section";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+ @Override
+ public Mark article(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="attrib";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+ @Override
+ public Mark aside(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="aside";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+ @Override
+ public Mark nav(String ... attribs) {
+ String[] a = new String[attribs.length+1];
+ a[0]="nav";
+ System.arraycopy(attribs, 0, a, 1, attribs.length);
+ return divID(a);
+ }
+
+// @Override
+// protected void importCSS(Imports imports) {
+// if(imports.css.size()==1) {
+// cssInline(imports.css.get(0));
+// } else {
+// text("<style type=\"text/css\">");
+// prettyln(forward);
+// forward.inc();
+// for(String str : imports.css) {
+// forward.print("@import url(\"");
+// forward.print(imports.themePath(null));
+// forward.print(str);
+// forward.print("\");");
+// prettyln(forward);
+// }
+// forward.dec();
+// forward.print("</style>");
+// prettyln(forward);
+// }
+// }
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML5Gen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML5Gen.java
new file mode 100644
index 0000000..d83004e
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTML5Gen.java
@@ -0,0 +1,155 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.io.Writer;
+
+import org.onap.aaf.misc.xgen.Mark;
+
+public class HTML5Gen extends HTMLGen {
+ public HTML5Gen(Writer w) {
+ super(w);
+ }
+
+ @Override
+ public HTMLGen html(String ... attrib) {
+ //forward.println("<!DOCTYPE html>");
+ incr("html",attrib);
+ return this;
+ }
+
+ @Override
+ public Mark head() {
+ Mark head = new Mark("head");
+ incr(head).directive("meta","charset=utf-8");
+ return head;
+ }
+
+ @Override
+ public Mark body(String ... attrs) {
+ Mark body = new Mark("body");
+ incr(body,"body",attrs);
+ //chromeFrame();
+ return body;
+ }
+
+ @Override
+ public HTML5Gen charset(String charset) {
+ forward.append("<meta charset=\"");
+ forward.append(charset);
+ forward.append("\">");
+ prettyln(forward);
+ return this;
+ }
+
+ @Override
+ public Mark header(String ... attribs) {
+ Mark mark = new Mark("header");
+ incr(mark, mark.comment, attribs);
+ return mark;
+ }
+
+ @Override
+ public Mark footer(String ... attribs) {
+ Mark mark = new Mark("footer");
+ incr(mark, mark.comment, attribs);
+ return mark;
+ }
+
+ @Override
+ public Mark section(String ... attribs) {
+ Mark mark = new Mark("section");
+ incr(mark, mark.comment,attribs);
+ return mark;
+ }
+
+ @Override
+ public Mark article(String ... attribs) {
+ Mark mark = new Mark("article");
+ incr(mark, mark.comment,attribs);
+ return mark;
+ }
+
+ @Override
+ public Mark aside(String ... attribs) {
+ Mark mark = new Mark("aside");
+ incr(mark, mark.comment,attribs);
+ return mark;
+ }
+
+ @Override
+ public Mark nav(String ... attribs) {
+ Mark mark = new Mark("nav");
+ incr(mark, mark.comment,attribs);
+ return mark;
+ }
+
+
+// @Override
+// protected void importCSS(Imports imports) {
+// if(imports.css.size() == 1) {
+// cssInline(imports.css.get(0));
+// } else {
+// for(String str : imports.css) {
+// forward.print("<link rel=\"stylesheet\" href=\"");
+// forward.print(imports.themePath(null));
+// forward.print(str);
+// forward.println("\">");
+// }
+// }
+// }
+//
+
+ /*
+ public void chromeFrame() {
+ this.textCR(0,"<!--[if IE]>");
+ Mark mark = new Mark();
+ this.leaf(mark, "script","type=text/javascript","src=http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js")
+ .end(mark);
+ this.incr(mark, "style")
+ .textCR(0,".chromeFrameInstallDefaultStyle {")
+ .textCR(1,"width: 100%; /* default is 800px * /")
+ .textCR(1,"border: 5px solid blue;")
+ .textCR(0,"}")
+ .end(mark);
+
+ this.incr(mark,"div","id=prompt"); // auto comment would break IE specific Script
+ // "if IE without GCF, prompt goes here"
+ this.text("Please load this plugin to run ClientSide Websockets")
+ .end(mark);
+
+ this.incr(mark, "script")
+ .textCR(0, "// The conditional ensures that this code will only execute in IE,")
+ .textCR(0, "// Therefore we can use the IE-specific attachEvent without worry")
+ .textCR(0, "window.attachEvent('onload', function() {")
+ .textCR(1,"CFInstall.check({")
+ .textCR(2,"mode: 'inline', // the default")
+ .textCR(2,"node: 'prompt'")
+ .textCR(1, "});")
+ .textCR(0, "});")
+ .end(mark);
+
+ this.textCR(0,"<![endif]-->");
+ }
+ */
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLCacheGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLCacheGen.java
new file mode 100644
index 0000000..8fba155
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLCacheGen.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.xgen.CacheGen;
+import org.onap.aaf.misc.xgen.Code;
+
+public class HTMLCacheGen extends CacheGen<HTMLGen> {
+ protected int flags;
+
+ public HTMLCacheGen(int flags, Code<HTMLGen> code) throws APIException,IOException {
+ super(flags, code);
+ this.flags = flags;
+ }
+
+ @Override
+ public HTMLGen create(int htmlStyle, Writer w) {
+ HTMLGen hg;
+ switch(htmlStyle&(CacheGen.HTML4|CacheGen.HTML5)) {
+ case CacheGen.HTML4:
+ hg = new HTML4Gen(w);
+ break;
+ case CacheGen.HTML5:
+ default:
+ hg = new HTML5Gen(w);
+ break;
+
+ }
+ hg.pretty = (htmlStyle&CacheGen.PRETTY)>0;
+ return hg;
+ }
+
+ protected HTMLGen clone(Writer w) {
+ return create(flags,w);
+ }
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLGen.java
new file mode 100644
index 0000000..92a89d7
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/HTMLGen.java
@@ -0,0 +1,240 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.io.Writer;
+
+import org.onap.aaf.misc.xgen.Mark;
+import org.onap.aaf.misc.xgen.XGen;
+
+public abstract class HTMLGen extends XGen<HTMLGen> {
+ public static final String A = "a";
+ public static final String P = "p";
+ public static final String LI = "li";
+ public static final String OL = "ol";
+ public static final String UL = "ul";
+
+
+ public static final String TABLE = "table";
+ public static final String THEAD = "thead";
+ public static final String TBODY = "tbody";
+ public static final String TR = "tr";
+ public static final String TH = "th";
+ public static final String TD = "td";
+
+ public static final String TITLE = "title";
+ public static final String H1 = "h1";
+ public static final String H2 = "h2";
+ public static final String H3 = "h3";
+ public static final String H4 = "h4";
+ public static final String H5 = "h5";
+
+
+
+ // --------------------------- HTML Version Specific -----------------------
+ public abstract HTMLGen html(String ... attributes);
+ public abstract HTMLGen charset(String charset);
+ public abstract Mark head();
+ public abstract Mark body(String ... attribs);
+
+
+ // HTML 5 has simplified sectioning
+ public abstract Mark header(String ... attribs);
+ public abstract Mark footer(String ... attribs);
+ public abstract Mark section(String ... attribs);
+ public abstract Mark article(String ... attribs);
+ public abstract Mark aside(String ... attribs);
+ public abstract Mark nav(String ... attribs);
+
+ // --------------------------- HTML Version Specific -----------------------
+
+ public HTMLGen imports(Imports imports) {
+ //this.imports=imports;
+ for(String str : imports.css) {
+ forward.print("<link rel=\"stylesheet\" href=\"");
+ forward.print(imports.themePath(null));
+ forward.print(str);
+ forward.println("\">");
+ }
+
+ for(String str : imports.js) {
+ forward.print("<script type=\"text/javascript\" src=\"");
+ forward.print(imports.themePath(null));
+ forward.print(str);
+ forward.println("\"></script>");
+ }
+ return this;
+ }
+
+ public HTMLGen jsVars(String ... attrs) {
+ forward.println("<script type=text/javascript>");
+ if(attrs!=null) {
+ for(int i=0; i<attrs.length;++i) {
+ forward.append(' ');
+ String[] split = attrs[i].split("=",2);
+ switch(split.length) {
+ case 2:
+ forward.print(" var ");
+ forward.append(split[0]);
+ forward.append("='");
+ forward.append(split[1]);
+ forward.println("';");
+ break;
+ }
+ }
+ }
+ forward.println("</script>");
+ return this;
+ }
+
+ public HTMLGen(Writer w) {
+ super(w);
+ }
+
+ /**
+ * Use "directive" to handle non-ended HTML tags like <meta ... > and <link ...>
+ * @param tag
+ * @param attrs
+ * @return
+ */
+ public HTMLGen directive(String tag, String ... attrs) {
+ forward.append('<');
+ forward.append(tag);
+ addAttrs(attrs);
+ forward.append('>');
+ if(pretty) {
+ forward.println();
+ }
+ return this;
+ }
+
+ public Mark divID(String ... attrs) {
+ Mark div;
+ if(attrs.length>0) {
+ div = new Mark(attrs[0]);
+ attrs[0]="id="+attrs[0];
+ } else {
+ div = new Mark();
+ }
+ incr(div, "div", attrs);
+ return div;
+ }
+
+ public HTMLGen img(String ... attrs) {
+ return tagOnly("img", attrs);
+ }
+
+ /**
+ * Input Cheesecake... creates a Label and Field in the form of Table Rows.
+ * Make sure you create a table first, ie. incr(HTMLGen.TABLE);
+ *
+ * Setting Required to "true" will add required Attribute to both Label and Field. In HTML5, "required" in the input will
+ * validate there is data in the fields before submitting. "required" does nothing for label, but allows for
+ * easy CSS coding... "label[required] { ... }", so that colors can be changed
+ *
+ * @param id
+ * @param label
+ * @param required
+ * @param attrs
+ * @return
+ */
+ public HTMLGen input(String id, String label, boolean required, String ... attrs) {
+ Mark mtr = new Mark(TR);
+ Mark mtd = new Mark(TD);
+ incr(mtr);
+ incr(mtd);
+ incr("label",true, "for="+id,required?"required":null).text(label).end();
+ end(mtd);
+ String nattrs[] = new String[attrs.length+(required?3:2)];
+ nattrs[0]="id="+id;
+ nattrs[1]="name="+id;
+ System.arraycopy(attrs, 0, nattrs, 2, attrs.length);
+ if(required) {
+ nattrs[nattrs.length-1]="required";
+ }
+ incr(mtd);
+ tagOnly("input",nattrs);
+ end(mtr);
+ return this;
+ }
+
+ // Common tags that do not have standard endings. These are here to help people who don't know to pick directive
+ public HTMLGen br() {
+ forward.append("<br>");
+ if(pretty) {
+ forward.println();
+ }
+ return this;
+ }
+
+ public HTMLGen p(String ... text) {
+ forward.append("<p>");
+ for(String s : text) {
+ forward.append(s);
+ }
+ if(pretty) {
+ forward.println();
+ }
+ return this;
+ }
+
+ public HTMLGen hr() {
+ forward.append("<hr>");
+ if(pretty) {
+ forward.println();
+ }
+ return this;
+ }
+
+ public JSGen js(Mark mark) {
+ return new JSGen(mark, this);
+ }
+
+ public JSGen js() {
+ return js(null);
+ }
+//
+// protected void cssInline(String filename) {
+// File file = new File(imports.webDir,filename);
+// try {
+// String line;
+// BufferedReader br = new BufferedReader(new FileReader(file));
+// try {
+// forward.print("<style>");
+// prettyln(forward);
+// while((line=br.readLine())!=null) {
+// forward.print((pretty?line:line.trim()));
+// prettyln(forward);
+// }
+// }finally {
+// forward.print("</style>");
+// prettyln(forward);
+// br.close();
+// }
+// } catch (IOException e) {
+// e.printStackTrace();
+// // Can't read, suffice to import normally?
+// // for now, just skip
+// }
+// }
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Imports.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Imports.java
new file mode 100644
index 0000000..90e8260
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Imports.java
@@ -0,0 +1,98 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Imports implements Thematic{
+ List<String> css,js;
+ public final int backdots;
+// public final File webDir;
+ private String theme;
+
+ public Imports(int backdots) {
+// this.webDir = webDir;
+
+ css = new ArrayList<String>();
+ js = new ArrayList<String>();
+ this.backdots = backdots;
+ theme = "";
+ }
+
+ public Imports css(String str) {
+ css.add(str);
+ return this;
+ }
+
+ public Imports js(String str) {
+ js.add(str);
+ return this;
+ }
+
+ public Imports theme(String str) {
+ theme = str==null?"":str;
+ return this;
+ }
+
+ /**
+ * Pass in a possible Theme. If it is "" or null, it will resolve to default Theme set in Imports
+ *
+ * @param theTheme
+ * @return
+ */
+ @Override
+ public String themePath(String theTheme) {
+ StringBuilder src = dots(new StringBuilder());
+ if(theTheme==null||theTheme.length()==0) {
+ src.append(theme);
+ if(theme.length()>0)src.append('/');
+ } else {
+ src.append(theTheme);
+ src.append('/');
+ }
+
+ return src.toString();
+ }
+
+ /**
+ * Pass in a possible Theme. If it is "" or null, it will resolve to default Theme set in Imports
+ *
+ * @param theTheme
+ * @return
+ */
+ @Override
+ public String themeResolve(String theTheme) {
+ return (theTheme==null||theTheme.length()==0)
+ ?theme
+ :theTheme;
+ }
+
+ public StringBuilder dots(StringBuilder src) {
+ for(int i=0;i<backdots;++i) {
+ src.append("../");
+ }
+ return src;
+ }
+
+};
+
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/JSGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/JSGen.java
new file mode 100644
index 0000000..be19a27
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/JSGen.java
@@ -0,0 +1,204 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.onap.aaf.misc.env.util.IndentPrintWriter;
+import org.onap.aaf.misc.xgen.Back;
+import org.onap.aaf.misc.xgen.Mark;
+
+
+public class JSGen {
+ private HTMLGen htmlGen;
+ private IndentPrintWriter ipw;
+ private Mark mark;
+
+ public JSGen(Mark mark, HTMLGen hg) {
+ this.mark = mark==null?new Mark():mark;
+ hg.incr(this.mark, "script", "language=javascript", "type=text/javascript");
+ htmlGen = hg;
+ ipw = hg.getWriter();
+ }
+
+ public JSGen inline(String filename, int tabstop) throws IOException {
+ BufferedReader br = new BufferedReader(new FileReader(filename));
+ int indent = htmlGen.getIndent();
+ try {
+ boolean pretty = htmlGen.pretty;
+ String line, el;
+ int l, end;
+ while((line=br.readLine())!=null) {
+ if(pretty) {
+ String[] elements = line.split("\t");
+
+ for(int i=0; i<elements.length;++i) {
+ el = elements[i];
+ l = el.length();
+ if(l==0) {// was a Tab
+ ipw.print(" ");
+ } else {
+ el = el.trim();
+ l = l-el.length();
+ end = l/tabstop;
+ for(int j=0;j<end;++j) {
+ ipw.print(" ");
+ }
+ end = l%tabstop;
+ for(int j=0;j<end;++j) {
+ ipw.print(' ');
+ }
+ if(i>0) ipw.print(' ');
+ ipw.print(el);
+ }
+ }
+ ipw.println();
+ } else {
+ ipw.print(line.trim());
+ }
+ }
+ } finally {
+ htmlGen.setIndent(indent);
+ try {
+ br.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return this;
+ }
+
+ public JSGen pst(String ... lines) {
+ return pst(null, lines);
+ }
+
+ public JSGen pst(Mark jm, String ... lines) {
+ if(lines.length>0) ipw.append(lines[0]);
+ ipw.append('(');
+ for(int i=1;i<lines.length;++i) {
+ ipw.print(lines[i]);
+ ipw.print(", ");
+ }
+ Back back;
+
+ if(htmlGen.pretty) {
+ back = new Back(");\n",false,false);
+ } else {
+ back = new Back(");",false,false);
+ }
+ int spot = htmlGen.pushBack(back);
+ if(jm!=null)jm.spot(spot);
+ return this;
+ }
+
+ public JSGen li(String ... lines) {
+ int current = ipw.getIndent();
+ for(int i=0;i<lines.length;++i) {
+ if(i==1)ipw.inc();
+ if(i>0)ipw.println();
+ ipw.print(lines[i]);
+ }
+ ipw.setIndent(current);
+ ipw.append(';');
+ if(htmlGen.pretty)ipw.println();
+ return this;
+ }
+
+ public JSGen text(String text) {
+ ipw.append(text);
+ if(htmlGen.pretty)ipw.println();
+ return this;
+ }
+
+ public JSGen function(String name, String ... params) {
+ return function(null, name, params);
+ }
+
+ public JSGen jqfunc(Mark mark, String name, String ... params) {
+ pst(mark,"$").function(name, params);
+ return this;
+ }
+
+ public JSGen function(Mark jm, String name, String ... params) {
+ ipw.print("function ");
+ ipw.print(name);
+ ipw.print('(');
+ for(int i=0;i<params.length;++i) {
+ if(i!=0)ipw.print(", ");
+ ipw.print(params[i]);
+ }
+ ipw.print(") {");
+ if(htmlGen.pretty) {
+ ipw.println();
+ ipw.inc();
+ }
+ int spot = htmlGen.pushBack(new Back("}",true,true));
+ if(jm!=null)jm.spot(spot);
+ return this;
+ }
+
+ public JSGen cb(String ... lines) {
+ return cb(null,lines);
+ }
+
+ public JSGen cb(Mark jm, String ... lines) {
+ int current = ipw.getIndent();
+ for(int i=0;i<lines.length;++i) {
+ if(i==1)ipw.inc();
+ if(i>0)ipw.println();
+ ipw.print(lines[i]);
+ }
+ ipw.setIndent(current);
+ ipw.print('{');
+ if(htmlGen.pretty) {
+ ipw.println();
+ ipw.inc();
+ }
+ int spot = htmlGen.pushBack(new Back("}",true,true));
+ if(jm!=null)jm.spot(spot);
+ return this;
+
+ }
+
+
+ public JSGen comment(String ... lines) {
+ if(htmlGen.pretty) {
+ for(int i=0;i<lines.length;++i) {
+ ipw.print("// ");
+ ipw.println(lines[i]);
+ }
+ }
+ return this;
+ }
+
+ public JSGen end(Mark mark) {
+ htmlGen.end(mark);
+ return this;
+ }
+
+ public HTMLGen done() {
+ return htmlGen.end(mark);
+ }
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/State.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/State.java
new file mode 100644
index 0000000..93f6da1
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/State.java
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+import org.onap.aaf.misc.env.Env;
+
+public interface State<ENV extends Env> {
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Thematic.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Thematic.java
new file mode 100644
index 0000000..98835dc
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/html/Thematic.java
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.html;
+
+public interface Thematic {
+ String themePath(String theTheme);
+ String themeResolve(String theTheme);
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLCacheGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLCacheGen.java
new file mode 100644
index 0000000..16ce436
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLCacheGen.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.xml;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.xgen.CacheGen;
+import org.onap.aaf.misc.xgen.Code;
+
+public class XMLCacheGen extends CacheGen<XMLGen> {
+
+ public XMLCacheGen(int flags, Code<XMLGen> code) throws APIException,
+ IOException {
+ super(flags, code);
+ }
+
+ @Override
+ public XMLGen create(int style, Writer w) {
+ XMLGen xg = new XMLGen(w);
+ xg.pretty = (style & PRETTY)==PRETTY;
+ return xg;
+ }
+
+}
diff --git a/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLGen.java b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLGen.java
new file mode 100644
index 0000000..1894567
--- /dev/null
+++ b/misc/xgen/src/main/java/org/onap/aaf/misc/xgen/xml/XMLGen.java
@@ -0,0 +1,44 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.misc.xgen.xml;
+
+import java.io.Writer;
+
+import org.onap.aaf.misc.xgen.XGen;;
+
+public class XMLGen extends XGen<XMLGen> {
+ private final String XML_TAG;
+
+ public XMLGen(Writer w) {
+ this(w,"UTF-8");
+ }
+
+ public XMLGen(Writer w, String encoding) {
+ super(w);
+ XML_TAG="<?xml version=\"1.0\" encoding=\"" + encoding + "\" standalone=\"yes\"?>";
+ }
+
+ public XMLGen xml() {
+ forward.println(XML_TAG);
+ return this;
+ }
+}