diff options
author | waqas.ikram <waqas.ikram@ericsson.com> | 2018-05-24 14:39:38 +0100 |
---|---|---|
committer | waqas.ikram <waqas.ikram@ericsson.com> | 2018-05-24 14:49:48 +0100 |
commit | 8e424a8db287f180c65b5e5fc32a6f23b4b2011f (patch) | |
tree | 80bab5706b2d3277e455558adfc5a75500ebc20c /model/utilities/src/main | |
parent | a94302f0e4af0d6136d1c694cfae12abc175dc55 (diff) |
Fixing typo in utilities module name
Change-Id: I7bae55aa9c9064fc4aea32bacba3baee196c10a0
Issue-ID: POLICY-855
Signed-off-by: waqas.ikram <waqas.ikram@ericsson.com>
Diffstat (limited to 'model/utilities/src/main')
17 files changed, 1693 insertions, 0 deletions
diff --git a/model/utilities/src/main/antlr4/org/onap/policy/apex/model/utilities/typeutils/ParametrizedType.g4 b/model/utilities/src/main/antlr4/org/onap/policy/apex/model/utilities/typeutils/ParametrizedType.g4 new file mode 100644 index 000000000..3a37d4043 --- /dev/null +++ b/model/utilities/src/main/antlr4/org/onap/policy/apex/model/utilities/typeutils/ParametrizedType.g4 @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------- +// ============LICENSE_START======================================================= +// Copyright (C) 2016-2018 Ericsson. All rights reserved. +// ================================================================================ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// ============LICENSE_END========================================================= +//------------------------------------------------------------------------------- + +grammar ParametrizedType; + +//For more information see: +// http://stackoverflow.com/questions/39401083/class-forname-equivalent-for-creating-parameterizedtypes-from-string +// https://github.com/KetothXupack/stackoverflow-answers/tree/master/q39401083 + +@parser::header { + //For more information see: + // http://stackoverflow.com/questions/39401083/class-forname-equivalent-for-creating-parameterizedtypes-from-string + // https://github.com/KetothXupack/stackoverflow-answers/tree/master/q39401083 + + + //Note: Unused Imports + //Since this is generated code compile warnings are to be expected and cannot always be suppressed + //See https://github.com/antlr/antlr4/issues/1192 + import org.onap.policy.apex.model.utilities.typeutils.ClassBuilder; +} + +type returns[ClassBuilder value] + : cls=CLASS { $value = ClassBuilder.parse($cls.text); } + | cls=CLASS { $value = ClassBuilder.parse($cls.text); } + LT head=type { $value.add($head.value); } + (COMMA tail=type { $value.add($tail.value); })* GT + ; + +GT : '>' + ; + +LT : '<' + ; + +COMMA + : ',' + ; + +CLASS + : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'$'|'.'|'_')* + ; diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/Assertions.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/Assertions.java new file mode 100644 index 000000000..c215f3fee --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/Assertions.java @@ -0,0 +1,154 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +/** + * The Class Assertions is a template class that is used as a shorthand for assertions in the source code. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public final class Assertions { + /** + * Private constructor used to prevent sub class instantiation. + */ + private Assertions() { + } + + /** + * Checks if a string parameter matches a regular expression. + * + * @param parameterName the string parameter name + * @param parameterValue the string parameter value + * @param pattern The regular expression + * @return the trimmed string + */ + public static String validateStringParameter(final String parameterName, final String parameterValue, final String pattern) { + argumentNotNull(parameterName, "parameter name is null"); + argumentNotNull(parameterValue, "parameter \"" + parameterName + "\" is null"); + argumentNotNull(pattern, "parameter pattern is null"); + + final String trimmedValue = parameterValue.trim(); + if (trimmedValue.matches(pattern)) { + return trimmedValue; + } + else { + throw new IllegalArgumentException( + "parameter \"" + parameterName + "\": value \"" + parameterValue + "\", does not match regular expression \"" + pattern + "\""); + } + } + + /** + * Used as a shorthand to check that method arguments are not null, throws IllegalArgumentException on error. + * + * @param <T> the generic type of the argument to check + * @param value the value of the type + * @param message the error message to issue + */ + public static <T> void argumentNotNull(final T value, final String message) { + if (value == null) { + throw new IllegalArgumentException(message); + } + } + + /** + * Used as a shorthand to check that method arguments are not false, throws IllegalArgumentException on error. + * + * @param value the value to check if false + * @param message the error message to issue + */ + public static void argumentNotFalse(final boolean value, final String message) { + if (!value) { + throw new IllegalArgumentException(message); + } + } + + /** + * Used as a shorthand to check that method arguments are not null, throws an exception of the specified type on error. + * + * @param <T> the generic type of the argument to check + * @param <E> the exception to throw if incoming value is null + * @param value the value of the type + * @param exceptionClass the class of exception to return an instance of + * @param message the error message to issue + * @throws E an instance of the passed Exception Class + */ + public static <T, E extends Exception> void argumentNotNull(final T value, final Class<E> exceptionClass, final String message) throws E { + if (value == null) { + // Instantiate the exception and throw it + try { + throw exceptionClass.getConstructor(String.class).newInstance(message); + } + catch (final Exception errorException) { + throw new IllegalArgumentException(message, errorException); + } + } + } + + /** + * Used as a shorthand to check that method argument is not false, throws an exception of the specified type on error. + * + * @param <E> the exception to throw if incoming value is false + * @param value the value to check if false + * @param exceptionClass the class of exception to return an instance of + * @param message the error message to issue + * @throws E an instance of the passed Exception Class + */ + public static <E extends Exception> void argumentNotFalse(final boolean value, final Class<E> exceptionClass, final String message) throws E { + if (!value) { + // Instantiate the exception and throw it + try { + throw exceptionClass.getConstructor(String.class).newInstance(message); + } + catch (final Exception errorException) { + throw new IllegalArgumentException(message, errorException); + } + } + } + + /** + * Used as a shorthand to check that an object is an instance of a given class, throws IllegalArgumentException on error. + * + * @param <T> the generic type of the argument to check + * @param objectInstance the object instance for which to check the class + * @param requiredClass the class that the object should be an instance of + * @throws IllegalArgumentException if the incoming object is not an instance of requiredClass + */ + public static <T> void instanceOf(final Object objectInstance, final Class<T> requiredClass) { + if (!requiredClass.isAssignableFrom(objectInstance.getClass())) { + throw new IllegalArgumentException(objectInstance.getClass().getCanonicalName() + " is not an instance of " + requiredClass.getCanonicalName()); + } + } + + /** + * Used as a shorthand to check that an instance of a class can be an instance of a given class, throws IllegalArgumentException on error. + * + * @param <T> the generic type of the argument to check + * @param checkClass the class to check + * @param requiredClass the class that the object should be an instance of + * @throws IllegalArgumentException if the incoming object is not an instance of requiredClass + */ + public static <T> void assignableFrom(final Class<?> checkClass, final Class<T> requiredClass) { + if (!requiredClass.isAssignableFrom(checkClass)) { + throw new IllegalArgumentException(checkClass.getCanonicalName() + " is not an instance of " + requiredClass.getCanonicalName()); + } + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java new file mode 100644 index 000000000..fb7207e0b --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/CollectionUtils.java @@ -0,0 +1,108 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.util.List; +import java.util.ListIterator; + +/** + * This is common utility class with static methods for handling collections. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class CollectionUtils { + /** + * Private constructor used to prevent sub class instantiation. + */ + private CollectionUtils() { + } + + /** + * Compare two lists, checks for equality, then for equality on members. + * + * @param <T> The type of the lists being compared + * @param leftList The leftmost List + * @param rightList The rightmost list + * @return an integer indicating how different the lists are + */ + public static <T> int compareLists(final List<? extends Comparable<T>> leftList, final List<? extends Comparable<T>> rightList) { + // Check for nulls + if (leftList == null && rightList == null) { + return 0; + } + if (leftList != null && rightList == null) { + return -1; + } + if (leftList == null) { + return 1; + } + + // Check for equality + if (leftList.equals(rightList)) { + return 0; + } + + return compareListEntries(leftList, rightList); + } + + /** + * Compare two lists for equality on members. + * + * @param <T> The type of the lists being compared + * @param leftList The leftmost List + * @param rightList The rightmost list + * @return an integer indicating how different the lists are + */ + private static <T> int compareListEntries(final List<? extends Comparable<T>> leftList, final List<? extends Comparable<T>> rightList) { + + // Iterate down the lists till we find a difference + final ListIterator<?> leftIterator = leftList.listIterator(); + final ListIterator<?> rightIterator = rightList.listIterator(); + + while (true) { + // Check the iterators + if (!leftIterator.hasNext() && !rightIterator.hasNext()) { + return 0; + } + if (leftIterator.hasNext() && !rightIterator.hasNext()) { + return -1; + } + if (!leftIterator.hasNext() && rightIterator.hasNext()) { + return 1; + } + + // Get the next objects + @SuppressWarnings("unchecked") + final T leftObject = (T) leftIterator.next(); + @SuppressWarnings("unchecked") + final T rightObject = (T) rightIterator.next(); + + // Compare the objects + @SuppressWarnings("unchecked") + final int comparisonResult = ((Comparable<T>) leftObject).compareTo(rightObject); + + // Check the comparison result + if (comparisonResult != 0) { + return comparisonResult; + } + } + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java new file mode 100644 index 000000000..00e5cb4cf --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/DirectoryUtils.java @@ -0,0 +1,138 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.io.File; + +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This is common utility class with static methods for handling directories. It is an abstract class to prevent any direct instantiation and private + * constructor to prevent extending this class. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class DirectoryUtils { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(DirectoryUtils.class); + + /** + * Private constructor used to prevent sub class instantiation. + */ + private DirectoryUtils() { + } + + /** + * Method to get an empty temporary directory in the system temporary directory on the local machine that will be deleted on (normal) shutdown. + * + * @param nameprefix The prefix of the filename. System.nanoTime() will be appended to the pattern to create a unique file pattern + * @return The temporary directory + */ + public static File getLocalTempDirectory(final String nameprefix) { + try { + // Get the name of the temporary directory + final String tempDirName = System.getProperty("java.io.tmpdir") + "/" + nameprefix + System.nanoTime(); + final File tempDir = new File(tempDirName); + + // Delete the directory if it already exists + if (tempDir.exists()) { + return null; + } + + // Make the directory + tempDir.mkdirs(); + + // Add a shutdown hook that deletes the directory contents when the JVM closes + Runtime.getRuntime().addShutdownHook(new DirectoryDeleteShutdownHook(tempDir)); + + LOGGER.trace("creating temp directory\"{}\" : ", tempDir.getAbsolutePath()); + return tempDir; + } + catch (final Exception e) { + LOGGER.debug("error creating temp directory\"{}\" : " + e.getMessage(), e); + return null; + } + } + + /** + * Method to recursively delete all the files in a directory. + * + * @param tempDir the directory to empty + * @return true if the operation succeeds, false otherwise + */ + public static boolean emptyDirectory(final File tempDir) { + // Sanity check + if (!tempDir.exists() || !tempDir.isDirectory()) { + return false; + } + + // Walk the directory structure deleting files as we go + final File[] files = tempDir.listFiles(); + if (files != null) { + for (final File directoryFile : files) { + // Check if this is a directory itself + if (directoryFile.isDirectory()) { + // Recurse into the sub directory and empty it + emptyDirectory(directoryFile); + } + + // Delete the directory entry + directoryFile.delete(); + } + } + + return true; + } +} + +/** + * The Class DirectoryShutdownHook removes the contents of a directory and the directory itself at shutdown. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +final class DirectoryDeleteShutdownHook extends Thread { + // The directory we are acting on + private final File tempDir; + + /** + * Constructor that defines the directory to act on at shutdown. + * + * @param tempDir The temporary directory to delete + */ + DirectoryDeleteShutdownHook(final File tempDir) { + this.tempDir = tempDir; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + if (tempDir.exists()) { + // Empty and delete the directory + DirectoryUtils.emptyDirectory(tempDir); + tempDir.delete(); + } + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/PropertyUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/PropertyUtils.java new file mode 100644 index 000000000..72f85638b --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/PropertyUtils.java @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.util.Map.Entry; + +/** + * Convenience methods for handling Java properties class instances. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class PropertyUtils { + /** + * Private constructor used to prevent sub class instantiation. + */ + private PropertyUtils() { + } + + /** + * Return all properties as a string. + * + * @return a string containing all the property values + */ + public static String getAllProperties() { + final StringBuilder builder = new StringBuilder(); + + for (final Entry<Object, Object> property : System.getProperties().entrySet()) { + builder.append(property.getKey().toString()); + builder.append('='); + builder.append(property.getValue().toString()); + builder.append('\n'); + } + + return builder.toString(); + } + + /** + * Checks if a property is set. If the property is set with no value or with a value of "true", this method returns true. It returns "false" if the property + * is not set or is set to false + * + * @param propertyName The property to check + * @return true if the property is set to true, false otherwise + */ + public static boolean propertySetOrTrue(final String propertyName) { + if (propertyName == null) { + return false; + } + + final String propertyValue = System.getProperty(propertyName); + if (propertyValue == null) { + return false; + } + + if (propertyValue.trim().length() == 0) { + return true; + } + + return new Boolean(propertyValue); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/ResourceUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/ResourceUtils.java new file mode 100644 index 000000000..588748dda --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/ResourceUtils.java @@ -0,0 +1,226 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This is common utility class with static methods for handling Java resources on the class path. It is an abstract class to prevent any direct instantiation + * and private constructor to prevent extending this class. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class ResourceUtils { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ResourceUtils.class); + + // The length of byte buffers used to read resources into strings + private static final int BYTE_BUFFER_LENGH = 1024; + + /** + * Private constructor used to prevent sub class instantiation. + */ + private ResourceUtils() { + } + + /** + * Method to resolve a resource; the local file system is checked first and then the class path is checked. + * + * @param resourceName The resource name + * @return A URL to a resource + */ + public static URL getURL4Resource(final String resourceName) { + // Check the local fine system first + final URL urlToResource = getLocalFile(resourceName); + + // Check if this is a local file + if (urlToResource != null) { + return urlToResource; + } + else { + // Resort to the class path + return getURLResource(resourceName); + } + } + + /** + * Method to return a resource as a string. The resource can be on the local file system or in the class path. The resource is resolved and loaded into a + * string. + * + * @param resourceName The resource name + * @return A string containing the resource + */ + public static String getResourceAsString(final String resourceName) { + // Get the resource as a stream, we'll convert it to a string then + final InputStream resourceStream = getResourceAsStream(resourceName); + if (resourceStream == null) { + return null; + } + + // Read the stream contents in to an output stream + final ByteArrayOutputStream resourceOutputStreamBuffer = new ByteArrayOutputStream(); + final byte[] resourceBuffer = new byte[BYTE_BUFFER_LENGH]; + int length; + try { + while ((length = resourceStream.read(resourceBuffer)) != -1) { + resourceOutputStreamBuffer.write(resourceBuffer, 0, length); + } + } + catch (final IOException e) { + LOGGER.debug("error reading resource stream \"{}\" : " + e.getMessage(), resourceName, e); + return null; + } + + return resourceOutputStreamBuffer.toString(); + } + + /** + * Method to return a resource as a stream. The resource can be on the local file system or in the class path. The resource is resolved and returned as a + * stream. + * + * @param resourceName The resource name + * @return A stream attached to the resource + */ + public static InputStream getResourceAsStream(final String resourceName) { + // Find a URL to the resource first + final URL urlToResource = getURL4Resource(resourceName); + + // Check if the resource exists + if (urlToResource == null) { + // No resource found + LOGGER.debug("cound not find resource \"{}\" : ", resourceName); + return null; + } + + // Read the resource into a string + try { + return urlToResource.openStream(); + } + catch (final IOException e) { + // Any of many IO exceptions such as the resource is a directory + LOGGER.debug("error attaching resource \"{}\" to stream : " + e.getMessage(), resourceName, e); + return null; + } + } + + /** + * Method to get a URL resource from the class path. + * + * @param resourceName The resource name + * @return The URL to the resource + */ + public static URL getURLResource(final String resourceName) { + try { + final ClassLoader classLoader = ResourceUtils.class.getClassLoader(); + + final String[] fileParts = resourceName.split("/"); + // Read the resource + URL url = classLoader.getResource(resourceName); + + // Check if the resource is defined + if (url != null) { + // Return the resource as a file name + LOGGER.debug("found URL resource \"{}\" : ", url); + return url; + } + else { + url = classLoader.getResource(fileParts[fileParts.length - 1]); + if (url == null) { + LOGGER.debug("cound not find URL resource \"{}\" : ", resourceName); + return null; + } + LOGGER.debug("found URL resource \"{}\" : ", url); + return url; + } + } + catch (final Exception e) { + LOGGER.debug("error getting URL resource \"{}\" : " + e.getMessage(), e); + return null; + } + } + + /** + * Method to get a URL resource from the local machine. + * + * @param resourceName The resource name + * @return The URL to the resource + */ + public static URL getLocalFile(final String resourceName) { + try { + // Input might already be in URL format + final URL ret = new URL(resourceName); + final File f = new File(ret.toURI()); + if (f.exists()) { + return ret; + } + } + catch (final Exception ignore) { + // We ignore exceptions here and catch them below + } + + try { + final File f = new File(resourceName); + // Check if the file exists + if (f.exists()) { + final URL urlret = f.toURI().toURL(); + LOGGER.debug("resource \"{}\" was found on the local file system", f.toURI().toURL()); + return urlret; + } + else { + LOGGER.debug("resource \"{}\" does not exist on the local file system", resourceName); + return null; + } + } + catch (final Exception e) { + LOGGER.debug("error finding resource \"{}\" : " + e.getMessage(), e); + return null; + } + } + + /** + * Gets the file path for a resource on the local file system or on the class path. + * + * @param resource the resource to the get the file path for + * @return the resource file path + */ + public static String getFilePath4Resource(final String resource) { + if (resource == null) { + return null; + } + + URL modelFileURL = getURL4Resource(resource); + if (modelFileURL != null) { + return modelFileURL.getPath(); + } + else { + return resource; + } + } + +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TextFileUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TextFileUtils.java new file mode 100644 index 000000000..d05245f23 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TextFileUtils.java @@ -0,0 +1,117 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * The Class TextFileUtils is class that provides useful functions for handling text files. Functions to read and wrtie text files to strings and strings are + * provided. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class TextFileUtils { + private static final int READER_CHAR_BUFFER_SIZE_4096 = 4096; + + private TextFileUtils() { + // This class cannot be initialized + } + + /** + * Method to return the contents of a text file as a string. + * + * @param textFilePath The path to the file as a string + * @return A string containing the contents of the file + * @throws IOException on errors reading text from the file + */ + public static String getTextFileAsString(final String textFilePath) throws IOException { + final File textFile = new File(textFilePath); + final FileInputStream textFileInputStream = new FileInputStream(textFile); + final byte[] textData = new byte[(int) textFile.length()]; + textFileInputStream.read(textData); + textFileInputStream.close(); + return new String(textData); + } + + /** + * Method to write contents of a string to a text file. + * + * @param outString The string to write + * @param textFilePath The path to the file as a string + * @throws IOException on errors reading text from the file + */ + public static void putStringAsTextFile(final String outString, final String textFilePath) throws IOException { + final File textFile = new File(textFilePath); + putStringAsFile(outString, textFile); + } + + /** + * Method to write contents of a string to a text file. + * + * @param outString The string to write + * @param textFile The file to write the string to + * @throws IOException on errors reading text from the file + */ + public static void putStringAsFile(final String outString, final File textFile) throws IOException { + final FileOutputStream textFileOutputStream = new FileOutputStream(textFile); + textFileOutputStream.write(outString.getBytes()); + textFileOutputStream.close(); + } + + /** + * Method to return the contents of a text steam as a string. + * + * @param textStream The stream + * @return A string containing the output of the stream as text + * @throws IOException on errors reading text from the file + */ + public static String getStreamAsString(final InputStream textStream) throws IOException { + return getReaderAsString(new BufferedReader(new InputStreamReader(textStream))); + } + + /** + * Method to return the contents of a reader steam as a string. This closes the reader after use + * + * @param textReader The reader + * @return A string containing the output of the reader as text + * @throws IOException on errors reading text from the file + */ + public static String getReaderAsString(final BufferedReader textReader) throws IOException { + + final StringBuilder builder = new StringBuilder(); + int charsRead = -1; + final char[] chars = new char[READER_CHAR_BUFFER_SIZE_4096]; + do { + charsRead = textReader.read(chars, 0, chars.length); + if (charsRead > 0) { + builder.append(chars, 0, charsRead); + } + } + while (charsRead > 0); + return builder.toString(); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java new file mode 100644 index 000000000..02ab0dd24 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TreeMapUtils.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities; + +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * This class provides utility functions for tree maps. A function to find the nearest match in the tree map to an input string is provided. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class TreeMapUtils { + + /** + * This class is a utility class that can't be instantiated. + */ + private TreeMapUtils() { + } + + /** + * Find the list of entries that matches a given word, for example "p" will match "put", "policy", and "push". + * + * @param <T> the generic type for the value of the tree map + * @param searchMap the map that the method operates on + * @param word the word to search for + * @return the list of entries in the {@code searchMap} that match the {@code word} + */ + public static <T> List<Entry<String, T>> findMatchingEntries(final TreeMap<String, T> searchMap, final String word) { + final List<Entry<String, T>> foundNodes = new ArrayList<>(); + + // A straight match check + if (searchMap.containsKey(word)) { + foundNodes.add(new SimpleEntry<>(word, searchMap.get(word))); + return foundNodes; + } + + // Set up the beginning point for our search for a list of near matches + String foundKeyword = searchMap.floorKey(word); + if (foundKeyword == null) { + foundKeyword = searchMap.firstKey(); + } + else { + foundKeyword = searchMap.higherKey(foundKeyword); + } + + // Find all the nodes that start with the word we are searching for + while (foundKeyword != null) { + if (foundKeyword.startsWith(word)) { + foundNodes.add(new SimpleEntry<>(foundKeyword, searchMap.get(foundKeyword))); + foundKeyword = searchMap.higherKey(foundKeyword); + } + else { + break; + } + } + return foundNodes; + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java new file mode 100644 index 000000000..8903ea803 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyComparer.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.comparison; + +/** + * This class compares two keys and returns their differences. It is used in bulk comparisons in models where maps of keys are being compared. The + * {@link KeyComparer} that is returned does the actual comparison + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @param <K> the type of key being compared + */ +public class KeyComparer<K> { + + /** + * Compare two keys and return their differences. + * + * @param leftKey The left key of the comparison + * @param rightKey The right key of the comparison + * @return The difference between the keys + */ + public KeyDifference<K> compareKeys(final K leftKey, final K rightKey) { + return new KeyDifference<>(leftKey, rightKey); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java new file mode 100644 index 000000000..43c44aefe --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyDifference.java @@ -0,0 +1,100 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.comparison; + +/** + * This class is used to template key differences for bulk key comparisons in models. It performs a difference check between two keys. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @param <K> the generic type + */ +public class KeyDifference<K> { + // The keys being compared + private K leftKey; + private K rightKey; + + /** + * Constructor used to set the keys being compared. + * + * @param leftKey the left key that is being compared + * @param rightKey the right key that is being compared + */ + public KeyDifference(final K leftKey, final K rightKey) { + this.leftKey = leftKey; + this.rightKey = rightKey; + } + + /** + * Gets the left key. + * + * @return the left key + */ + public K getLeftKey() { + return leftKey; + } + + /** + * Gets the right key. + * + * @return the right key + */ + public K getRightKey() { + return rightKey; + } + + /** + * Checks if the left and right keys are equal. + * + * @return true, if checks if is equal + */ + public boolean isEqual() { + return leftKey.equals(rightKey); + } + + /** + * Gets a string representation of the difference between the keys. + * + * @param diffsOnly if set, then a blank string is returned if the keys are equal + * @return the difference between the keys as a string + */ + public String asString(final boolean diffsOnly) { + StringBuilder builder = new StringBuilder(); + + if (leftKey.equals(rightKey)) { + if (!diffsOnly) { + builder.append("left key "); + builder.append(leftKey); + builder.append(" equals right key "); + builder.append(rightKey); + builder.append('\n'); + } + } + else { + builder.append("left key "); + builder.append(leftKey); + builder.append(" and right key "); + builder.append(rightKey); + builder.append(" differ\n"); + } + + return builder.toString(); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java new file mode 100644 index 000000000..b11f77a0f --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapComparer.java @@ -0,0 +1,95 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.comparison; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * Compare two maps and returns their differences. The types of the keys and the values in the two maps being comapred must be the same. The class returns + * entries that are only in the left map, only in the right map, entries that have identical keys and different values and entries that have different keys and + * different values in a {@link KeyedMapDifference} instance. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @param <K> the type of the keys in the maps being compared + * @param <V> the type of the values in the maps being compared + */ +public class KeyedMapComparer<K, V> { + /** + * Compare two maps and return their differences in a {@link KeyedMapDifference} instance. + * + * @param leftMap The left map to be compared + * @param rightMap The right map to be compared + * @return The common, left only, and right only maps in a {@link KeyedMapDifference} instance + */ + public KeyedMapDifference<K, V> compareMaps(final Map<K, V> leftMap, final Map<K, V> rightMap) { + KeyedMapDifference<K, V> result = new KeyedMapDifference<>(); + + // Get the keys that are only in the left map + Set<K> leftOnlyKeys = new TreeSet<>(leftMap.keySet()); + leftOnlyKeys.removeAll(rightMap.keySet()); + + // Get the keys that are only in the right map + Set<K> rightOnlyKeys = new TreeSet<>(rightMap.keySet()); + rightOnlyKeys.removeAll(leftMap.keySet()); + + // Find the keys common across both maps + Set<K> commonKeys = new TreeSet<>(rightMap.keySet()); + commonKeys.addAll(leftMap.keySet()); + commonKeys.removeAll(leftOnlyKeys); + commonKeys.removeAll(rightOnlyKeys); + + // Now save the left values + for (K key : leftOnlyKeys) { + result.getLeftOnly().put(key, leftMap.get(key)); + } + + // Now save the right values + for (K key : rightOnlyKeys) { + result.getRightOnly().put(key, rightMap.get(key)); + } + + // Save the common values to two maps, an identical and different map + for (K key : commonKeys) { + // Check if the values are identical in each map + V leftValue = leftMap.get(key); + V rightValue = rightMap.get(key); + + // Store as appropriate + if (leftValue.equals(rightValue)) { + result.getIdenticalValues().put(key, leftValue); + } + else { + // Store the two values + List<V> valueList = new ArrayList<>(); + valueList.add(leftValue); + valueList.add(rightValue); + + result.getDifferentValues().put(key, valueList); + } + } + + return result; + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java new file mode 100644 index 000000000..0f9d6ca50 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/KeyedMapDifference.java @@ -0,0 +1,206 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.comparison; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * This class holds the result of a difference check between two keyed maps. Four results are returned in the class. The {@code leftOnly} result is the entries + * that appear only in the left map. the {@code rightOnly} result is the entries that appear only in the right map. The {@code differentValues} result are the + * entries that have the same key but different values in the maps being compared. The {@code identicalValues} result are the entries with identical keys and + * values in both maps being compared. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @param <K> the generic type + * @param <V> the generic type + */ +public class KeyedMapDifference<K, V> { + private static final String KEY = "key="; + private static final String VALUE = ",value="; + + // Three maps to hold the comparison result + private Map<K, V> leftOnly = new TreeMap<>(); + private Map<K, V> rightOnly = new TreeMap<>(); + private Map<K, V> identicalValues = new TreeMap<>(); + private Map<K, List<V>> differentValues = new TreeMap<>(); + + /** + * Gets the entries that were found only in the left map. + * + * @return the entries only in the left map + */ + public Map<K, V> getLeftOnly() { + return leftOnly; + } + + /** + * Gets the entries that were found only in the right map. + * + * @return the entries only in the right map + */ + public Map<K, V> getRightOnly() { + return rightOnly; + } + + /** + * Gets the entries that were identical (keys and values the same) in both maps. + * + * @return the identical entries + */ + public Map<K, V> getIdenticalValues() { + return identicalValues; + } + + /** + * Gets the entries that had the same key but different values in both maps. + * + * @return the entries that were different. There are two values in the list of values for each entry. The first value is the value that was in the left map + * and the second value is the value that was in the right map. + */ + public Map<K, List<V>> getDifferentValues() { + return differentValues; + } + + /** + * Return a string representation of the differences. + * + * @param diffsOnly if set, then a blank string is returned if the maps are equal + * @param keysOnly if set, then a terse string that prints only the keys is returned, otherwise both keys and values are printed + * @return the string + */ + public String asString(final boolean diffsOnly, final boolean keysOnly) { + StringBuilder builder = new StringBuilder(); + + if (leftOnly.isEmpty()) { + if (!diffsOnly) { + builder.append("*** all left keys in right\n"); + } + } + else { + builder.append(getInOneSideOnlyAsString(leftOnly, "left", keysOnly)); + } + + if (leftOnly.isEmpty()) { + if (!diffsOnly) { + builder.append("*** all right keys in left\n"); + } + } + else { + builder.append(getInOneSideOnlyAsString(rightOnly, "right", keysOnly)); + } + + if (differentValues.isEmpty()) { + if (!diffsOnly) { + builder.append("*** all values in left and right are identical\n"); + } + } + else { + builder.append(getDifferencesAsString(keysOnly)); + } + + if (!diffsOnly) { + builder.append(getIdenticalsAsString(keysOnly)); + } + + return builder.toString(); + } + + /** + * Output the entries in a map with entries that are in one side only as a string + * @param sideMap the map for the side being checked + * @param sideMapString the string that represents the map in output strings + * @param keysOnly if true, just add key information and not entries + * @return the entries as a string + */ + private Object getInOneSideOnlyAsString(final Map<K, V> sideMap, final String sideMapString, final boolean keysOnly) { + StringBuilder builder = new StringBuilder(); + + builder.append("*** list of keys on " + sideMapString + " only\n"); + for (Entry<K, V> leftEntry : sideMap.entrySet()) { + builder.append(KEY); + builder.append(leftEntry.getKey()); + if (!keysOnly) { + builder.append(VALUE); + builder.append(leftEntry.getValue()); + } + builder.append('\n'); + } + + return builder.toString(); + } + + /** + * Output the differences between two the maps as a string + * @param keysOnly if true, just add key information and not entries + * @return the differences as a string + */ + private String getDifferencesAsString(final boolean keysOnly) { + StringBuilder builder = new StringBuilder(); + + builder.append("*** list of differing entries between left and right\n"); + for (Entry<K, List<V>> differentEntry : differentValues.entrySet()) { + builder.append(KEY); + builder.append(differentEntry.getKey()); + if (!keysOnly) { + builder.append(",values={"); + boolean first = true; + for (V differentEntryValue : differentEntry.getValue()) { + builder.append(differentEntryValue); + if (first) { + first = false; + } + else { + builder.append(','); + } + } + builder.append("}"); + } + builder.append('\n'); + } + + return builder.toString(); + } + + /** + * Output the identical entries in the maps as a string + * @param keysOnly if true, just add key information and not entries + * @return the identical entries as a string + */ + private String getIdenticalsAsString(final boolean keysOnly) { + StringBuilder builder = new StringBuilder(); + + builder.append("*** list of identical entries in left and right\n"); + for (Entry<K, V> identicalEntry : identicalValues.entrySet()) { + builder.append(KEY); + builder.append(identicalEntry.getKey()); + if (!keysOnly) { + builder.append(VALUE); + builder.append(identicalEntry.getValue()); + } + builder.append('\n'); + } + + return builder.toString(); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java new file mode 100644 index 000000000..f0488eacd --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/comparison/package-info.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides utility template classes that compare keys and maps of any type. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.model.utilities.comparison; diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/package-info.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/package-info.java new file mode 100644 index 000000000..446d009ba --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/package-info.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides utility classes that are used in APEX models and indeed in other packages that use APEX models. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.model.utilities; diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/ClassBuilder.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/ClassBuilder.java new file mode 100644 index 000000000..e806bd7a0 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/ClassBuilder.java @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.typeutils; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +//CHECKSTYLE:OFF: checkstyle:IllegalImport +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; +//CHECKSTYLE:ON: checkstyle:IllegalImport + +/** + * This class is a utility class that builds a class with a set of user defined fields. It is used to get the Type of fields in Java schemas<br> + * For more information see:<br> + * <a href="http://stackoverflow.com/questions/39401083/class-forname-equivalent-for-creating-parameterizedtypes-from-string"> + * http://stackoverflow.com/questions/39401083/class-forname-equivalent-for-creating-parameterizedtypes-from-string</a><br> + * <a href="https://github.com/KetothXupack/stackoverflow-answers/tree/master/q39401083"> + * https://github.com/KetothXupack/stackoverflow-answers/tree/master/q39401083</a><br> + */ +@SuppressWarnings("restriction") +public class ClassBuilder { + private final Class<?> clazz; + private final List<ClassBuilder> parameters = new ArrayList<>(); + + /** + * Constructor that sets the class for the class builder. + * + * @param clazz the class of the class builder + */ + public ClassBuilder(final Class<?> clazz) { + this.clazz = clazz; + } + + /** + * Creates a {@link ClassBuilder} instance for a class with the given class name. + * + * @param className the class name of the class builder to create + * @return the class builder that is created + */ + public static ClassBuilder parse(final String className) { + try { + return new ClassBuilder(Class.forName(className)); + } + catch (ClassNotFoundException e) { + try { + return new ClassBuilder(Class.forName("java.lang." + className)); + } + catch (Exception ignore) { + throw new IllegalArgumentException("Class '" + className + "' not found. Also looked for a class called 'java.lang." + className + "'", e); + } + } + } + + /** + * Adds a field to the class builder. Each field is itself a class builder. + * + * @param fieldBuilder the class builder for the field + */ + public void add(final ClassBuilder fieldBuilder) { + parameters.add(fieldBuilder); + } + + /** + * Builds the {@link Type} of the class. + * + * @return the {@link Type} of the class + */ + public Type build() { + // class is not parameterized + if (parameters.isEmpty()) { + return clazz; + } + Type[] paramtypes = new Type[parameters.size()]; + int i = 0; + for (ClassBuilder classBuilder : parameters) { + paramtypes[i++] = classBuilder.build(); + } + return ParameterizedTypeImpl.make(clazz, paramtypes, null); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/TypeBuilder.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/TypeBuilder.java new file mode 100644 index 000000000..a3f22a446 --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/TypeBuilder.java @@ -0,0 +1,114 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.model.utilities.typeutils; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.BailErrorStrategy; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; + +/** + * This class . + */ +public final class TypeBuilder { + /** + * Private constructor used to prevent sub class instantiation. + */ + private TypeBuilder() { + } + + /** + * Builds the Type of the Type string that was input. + * + * @param type the java Type as a string + * @return the Type of the string that was input + */ + public static Type build(final String type) { + if (type == null || type.length() == 0) { + throw new IllegalArgumentException("Blank type string passed to " + TypeBuilder.class.getCanonicalName() + ".build(String type)"); + } + + try { + final CharStream stream = new ANTLRInputStream(type); + final TokenStream tokenStream = new CommonTokenStream(new ParametrizedTypeLexer(stream)); + + final ParametrizedTypeParser parser = new ParametrizedTypeParser(tokenStream); + parser.removeErrorListeners(); + parser.setErrorHandler(new BailErrorStrategy()); + parser.setBuildParseTree(true); + return parser.type().value.build(); + } + catch (final Exception e) { + throw new IllegalArgumentException("Failed to build type '" + type + "': " + e, e); + } + } + + /** + * Gets the class of Java Type. + * + * @param type the java Type as a string + * @return the java Type + */ + public static Class<?> getJavaTypeClass(final String type) { + return getJavaTypeClass(build(type)); + } + + /** + * Gets the class of Java Type. + * + * @param type the java Type as a Type + * @return the java Type + */ + public static Class<?> getJavaTypeClass(final Type type) { + if (type instanceof Class<?>) { + return (Class<?>) type; + } + else if (type instanceof ParameterizedType) { + final Type raw = ((ParameterizedType) type).getRawType(); + if (!(raw instanceof Class<?>)) { + throw new IllegalArgumentException( + "The Parameterised javatype " + type + " with base type " + raw + " is not a Java 'Class' that can be instantiated"); + } + return (Class<?>) raw; + } + throw new IllegalArgumentException("The Parameterised javatype " + type + " is not a Java 'Type' that has a 'Class'"); + } + + /** + * Gets the parameters of a Java Type. + * + * @param type the Java Type + * @return the parameters of the java Type + */ + public static Type[] getJavaTypeParameters(final Type type) { + if (type instanceof Class<?>) { + return new Type[0]; + } + else if (type instanceof ParameterizedType) { + return ((ParameterizedType) type).getActualTypeArguments(); + } + throw new IllegalArgumentException("\"The Parameterised javatype \" + type + \" is not a Java 'Type' that has parameter types"); + } +} diff --git a/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/package-info.java b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/package-info.java new file mode 100644 index 000000000..ed4b079bf --- /dev/null +++ b/model/utilities/src/main/java/org/onap/policy/apex/model/utilities/typeutils/package-info.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides utility classes that operate on and work with Java Types. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.model.utilities.typeutils; |