diff options
author | Instrumental <jcgmisc@stl.gathman.org> | 2018-03-26 13:37:04 -0700 |
---|---|---|
committer | Instrumental <jcgmisc@stl.gathman.org> | 2018-03-26 13:48:11 -0700 |
commit | ac1e1ec76e9125206be91a2f32c7104c9392dc9a (patch) | |
tree | 91250899236fa337365f4268e9dc5f1da48907d7 /misc | |
parent | 686d16c26d0435f892de66755ac8bc2383a739d2 (diff) |
AT&T 2.0.19 Code drop, stage 1
Issue-ID: AAF-197
Change-Id: Ie75c6c322e9c4e7982b198cb48439e926c3a1fbd
Signed-off-by: Instrumental <jcgmisc@stl.gathman.org>
Diffstat (limited to 'misc')
141 files changed, 15491 insertions, 0 deletions
diff --git a/misc/.gitignore b/misc/.gitignore new file mode 100644 index 00000000..0c2b833e --- /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 00000000..51037e60 --- /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 00000000..e724f8ef --- /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 00000000..2b663450 --- /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 00000000..4750b3ef --- /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 00000000..995819e9 --- /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 00000000..2c24cb12 --- /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 00000000..4ce7eaf9 --- /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 00000000..039cb2f4 --- /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 00000000..9e621136 --- /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 00000000..71f79222 --- /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 00000000..27f423b0 --- /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 00000000..1aba7465 --- /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 00000000..2bfc027b --- /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 00000000..32dda01d --- /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 00000000..d4e28688 --- /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 00000000..1eab8db8 --- /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 00000000..3e14511a --- /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 00000000..7ceaf953 --- /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 00000000..09397dec --- /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 00000000..e2024726 --- /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 00000000..4a1033fe --- /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 00000000..4e34dcdc --- /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 00000000..90fb1f2b --- /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 00000000..3d29366a --- /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 00000000..053d4d6f --- /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 00000000..ced64e8a --- /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 00000000..7c166139 --- /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 00000000..dfc12b6e --- /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 00000000..6b503130 --- /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 00000000..a04b63e6 --- /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 00000000..5c4a80b3 --- /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 00000000..65fe9d80 --- /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 00000000..eb33ff59 --- /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 00000000..a882c748 --- /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 00000000..84a78bfd --- /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 00000000..44da65e6 --- /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 00000000..5cda17f0 --- /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 00000000..74fcc830 --- /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 00000000..e1c54c63 --- /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 00000000..9679d841 --- /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 00000000..5bed4fd8 --- /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 00000000..f35ffb7a --- /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 00000000..7e60bce8 --- /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 00000000..65c5a36e --- /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 00000000..c5f57b98 --- /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 00000000..6ec72ba4 --- /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 00000000..a4342614 --- /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 00000000..7dcdf34f --- /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 00000000..74fbef65 --- /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 00000000..0bce4733 --- /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 00000000..d6ac850d --- /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 00000000..17cbff37 --- /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 00000000..cd11dcb3 --- /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 00000000..56153393 --- /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 00000000..79a74031 --- /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 00000000..c2a1f91a --- /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 00000000..cea4d859 --- /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 00000000..01acf218 --- /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 00000000..45aeec64 --- /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 00000000..facb2f7a --- /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 00000000..a8830b47 --- /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 00000000..6e23ce63 --- /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 00000000..d5c9062f --- /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 00000000..2079777e --- /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 00000000..4eba2fd5 --- /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 00000000..3b314b88 --- /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 00000000..1f3c1490 --- /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 00000000..725389c9 --- /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 00000000..51926573 --- /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 00000000..2708aa2f --- /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 00000000..5f38c8c7 --- /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 00000000..bb6784c8 --- /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 00000000..51cec078 --- /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 00000000..d482b247 --- /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 00000000..38b021ea --- /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 00000000..567a6261 --- /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 00000000..db7b956c --- /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 00000000..2340bdb6 --- /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 00000000..bf833f7b --- /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 00000000..f3ce1c22 --- /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 00000000..657baf5c --- /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 00000000..d986776d --- /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 00000000..326c5bba --- /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 00000000..07bd40f0 --- /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 00000000..45c27052 --- /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 00000000..f1cde6e5 --- /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 00000000..68baebb6 --- /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 00000000..446c3c9c --- /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 00000000..05c75b7e --- /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 00000000..1655928d --- /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 00000000..5249a17a --- /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 00000000..3006f897 --- /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 00000000..1de14e82 --- /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 00000000..b3632a14 --- /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 00000000..8aa29829 --- /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 00000000..589d0920 --- /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 00000000..cb8b6557 --- /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 00000000..aac9ac69 --- /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 00000000..2337c3c9 --- /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 00000000..6045141d --- /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 00000000..3d7d1b4e --- /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 00000000..eaa7a74a --- /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 00000000..e0a33fb4 --- /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 00000000..b4d137e8 --- /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 00000000..5533964b --- /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 00000000..121deea0 --- /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 00000000..58813621 --- /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 00000000..2a48edc4 --- /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 00000000..f72b6e69 --- /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 00000000..cff5b43a --- /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 00000000..07c73196 --- /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 00000000..47953007 --- /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 00000000..6047c03c --- /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 00000000..1209e77d --- /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 00000000..5d76e3cb --- /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 00000000..ab0c921a --- /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 00000000..5c709adc --- /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 00000000..5e96a379 --- /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 00000000..932277de --- /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 00000000..75472cfd --- /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 00000000..982920a7 --- /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 00000000..71c10aa4 --- /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 00000000..2a9ee674 --- /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 00000000..aa3d1fed --- /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 00000000..96418df6 --- /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 00000000..1b798fb6 --- /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 00000000..92dc5b96 --- /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 00000000..8eb98ff6 --- /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 00000000..09c03111 --- /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 00000000..95c4060b --- /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 00000000..dfab12cb --- /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 00000000..d83004e8 --- /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 00000000..8fba1555 --- /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 00000000..92a89d7d --- /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 00000000..90e82607 --- /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 00000000..be19a274 --- /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 00000000..93f6da1b --- /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 00000000..98835dc5 --- /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 00000000..16ce436b --- /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 00000000..18945672 --- /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; + } +} |