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/env/src/main/java/org | |
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/env/src/main/java/org')
55 files changed, 6741 insertions, 0 deletions
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 { + } + +} |