From b6977d2f7ce64ece732ac1a1a0525dac972d7ccf Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Wed, 17 Feb 2021 15:23:38 -0500 Subject: Fix sonars in apex-pdp Addressed the following issues: - initialize mocks before use - use parameterized queries - Random() is not secure - provide parameterized type for generics - unused imports - constructor visibility - use compute() instead of containsKey()/put() - make final fields static - rename constants to all upper case - no assert() in Thread.run() methods - nested try - nested if/else - too many break/continue - use try-with-resources - repeatable annotations - overlapping characters in reg ex - hashcode is not sufficient in compareTo() - need equals() with compareTo() - make class an interface - use parameterized test - multiple calls in assert() - log or re-throw - use different type of lambda - use parameterized logging - use StringBuilder instead of concatenation - use StandardCharsets.UTF_8 Issue-ID: POLICY-2906 Change-Id: I2cf8c885e3e22c2c6cbe6403a34906928afad022 Signed-off-by: Jim Hahn --- .../apex/model/basicmodel/concepts/AxConcept.java | 5 +- .../apex/model/basicmodel/concepts/AxKey.java | 5 +- .../apex/model/basicmodel/concepts/AxKeyInfo.java | 11 +++- .../basicmodel/concepts/AxKeyInformation.java | 10 ++-- .../apex/model/basicmodel/concepts/AxModel.java | 6 +-- .../model/basicmodel/dao/impl/DefaultApexDao.java | 63 +++++++++++++++------- .../model/basicmodel/handling/ApexModelReader.java | 3 +- .../basicmodel/handling/ApexModelReaderTest.java | 4 ++ .../basicmodel/handling/ApexModelWriterTest.java | 4 ++ .../contextmodel/concepts/AxContextAlbum.java | 8 ++- .../contextmodel/concepts/AxContextModel.java | 14 ++--- .../model/enginemodel/concepts/AxEngineModel.java | 20 +++---- .../model/eventmodel/concepts/AxEventModel.java | 10 ++-- .../apex/model/eventmodel/concepts/AxField.java | 6 +-- .../model/policymodel/concepts/AxPolicyModel.java | 24 ++++----- .../apex/model/policymodel/concepts/AxState.java | 10 ++-- .../model/policymodel/concepts/AxStateOutput.java | 14 ++--- .../policymodel/concepts/AxStateTaskReference.java | 10 ++-- .../model/policymodel/concepts/AxStateTree.java | 26 +++++++-- .../apex/model/utilities/CollectionUtils.java | 9 ++-- .../policy/apex/model/utilities/TreeMapUtils.java | 3 +- 21 files changed, 160 insertions(+), 105 deletions(-) (limited to 'model') diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java index 8bbc652e7..0e2c6bef2 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxConcept.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +42,7 @@ public abstract class AxConcept implements Serializable, Comparable { /** * Default constructor. */ - public AxConcept() { + protected AxConcept() { // Default constructor } @@ -50,7 +51,7 @@ public abstract class AxConcept implements Serializable, Comparable { * * @param copyConcept the concept to copy from */ - public AxConcept(final AxConcept copyConcept) { + protected AxConcept(final AxConcept copyConcept) { Assertions.argumentNotNull(copyConcept, "copy concept may not be null"); copyConcept.copyTo(this); } diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java index 743847358..1b6f0148f 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKey.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +68,7 @@ public abstract class AxKey extends AxConcept { /** * Default constructor. */ - public AxKey() { + protected AxKey() { super(); } @@ -76,7 +77,7 @@ public abstract class AxKey extends AxConcept { * * @param copyConcept the concept to copy from */ - public AxKey(final AxKey copyConcept) { + protected AxKey(final AxKey copyConcept) { super(copyConcept); } diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java index fc8c0cd14..4b84a403a 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInfo.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +64,10 @@ public class AxKeyInfo extends AxConcept { private static final int MAX_DESCRIPTION_LENGTH_8192 = 8192; private static final int UUID_BYTE_LENGTH_16 = 16; - private static final Random sharedRandom = new Random(); + /* + * This is not used for encryption/security, thus disabling sonar. + */ + private static final Random sharedRandom = new Random(); // NOSONAR @EmbeddedId @XmlElement(name = "key", required = true) @@ -334,7 +338,10 @@ public class AxKeyInfo extends AxConcept { public static UUID generateReproducibleUuid(final String seed) { Random random = sharedRandom; if (!StringUtils.isEmpty(seed)) { - random = new Random(seed.hashCode()); + /* + * This is not used for encryption/security, thus disabling sonar. + */ + random = new Random(seed.hashCode()); // NOSONAR } final byte[] array = new byte[UUID_BYTE_LENGTH_16]; random.nextBytes(array); diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java index 446a00a68..2619d2eea 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxKeyInformation.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019-2020 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,12 +149,13 @@ public class AxKeyInformation extends AxConcept implements AxConceptGetter { final AxKeyInfo keyInfo = new AxKeyInfo(artifactKey); // generate a reproducible UUID keyInfo.setUuid(AxKeyInfo.generateReproducibleUuid(keyInfo.getId() + keyInfo.getDescription())); - keyInfoMap.put(artifactKey, keyInfo); - } + return keyInfo; + }); } } @@ -422,4 +424,4 @@ public class AxKeyInformation extends AxConcept implements AxConceptGetter((NavigableMap) keyInfoMap).getAll(conceptKeyName, conceptKeyVersion); } -} \ No newline at end of file +} diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java index 9c71638fc..da6fb49c6 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/concepts/AxModel.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +31,6 @@ import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; @@ -76,8 +76,8 @@ public class AxModel extends AxConcept { // @formatter:off @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({ @JoinColumn(name = "keyInformationName", referencedColumnName = "name"), - @JoinColumn(name = "keyInformationVersion", referencedColumnName = "version") }) + @JoinColumn(name = "keyInformationName", referencedColumnName = "name") + @JoinColumn(name = "keyInformationVersion", referencedColumnName = "version") @XmlElement(name = "keyInformation", required = true) @XmlJavaTypeAdapter(KeyInfoMarshalFilter.class) private AxKeyInformation keyInformation; diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/dao/impl/DefaultApexDao.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/dao/impl/DefaultApexDao.java index 39e8b0def..738d15ed3 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/dao/impl/DefaultApexDao.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/dao/impl/DefaultApexDao.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019-2020 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,12 +48,18 @@ import org.slf4j.ext.XLoggerFactory; public class DefaultApexDao implements ApexDao { private static final XLogger LOGGER = XLoggerFactory.getXLogger(DefaultApexDao.class); + private static final String COL_LOCALNAME = "local_name"; + private static final String COL_PARENT_VERSION = "parent_version"; + private static final String COL_PARENT_NAME = "parent_name"; + private static final String COL_VERSION = "key_version"; + private static final String COL_NAME = "key_name"; + private static final String SELECT_C_FROM = "SELECT c FROM "; - private static final String AND_C_KEY_LOCAL_NAME = "' AND c.key.localName='"; - private static final String AND_C_KEY_PARENT_KEY_VERSION = "' AND c.key.parentKeyVersion='"; - private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName='"; - private static final String AND_C_KEY_VERSION = "' AND c.key.version='"; - private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name='"; + private static final String AND_C_KEY_LOCAL_NAME = " AND c.key.localName=:" + COL_LOCALNAME; + private static final String AND_C_KEY_PARENT_KEY_VERSION = " AND c.key.parentKeyVersion=:" + COL_PARENT_VERSION; + private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName=:" + COL_PARENT_NAME; + private static final String AND_C_KEY_VERSION = " AND c.key.version=:" + COL_VERSION; + private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name=:" + COL_NAME; private static final String DELETE_FROM = "DELETE FROM "; // Entity manager for JPA @@ -151,8 +158,10 @@ public class DefaultApexDao implements ApexDao { final EntityManager mg = getEntityManager(); try { mg.getTransaction().begin(); - mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() - + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + AND_C_KEY_VERSION, someClass) + .setParameter(COL_NAME, key.getName()) + .setParameter(COL_VERSION, key.getVersion()) + .executeUpdate(); mg.getTransaction().commit(); } finally { mg.close(); @@ -171,8 +180,12 @@ public class DefaultApexDao implements ApexDao { try { mg.getTransaction().begin(); mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME - + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() - + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).executeUpdate(); + + AND_C_KEY_PARENT_KEY_VERSION + + AND_C_KEY_LOCAL_NAME, someClass) + .setParameter(COL_PARENT_NAME, key.getParentKeyName()) + .setParameter(COL_PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(COL_LOCALNAME, key.getLocalName()) + .executeUpdate(); mg.getTransaction().commit(); } finally { mg.close(); @@ -234,7 +247,10 @@ public class DefaultApexDao implements ApexDao { mg.getTransaction().begin(); for (final AxArtifactKey key : keys) { deletedCount += mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME - + key.getName() + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + + AND_C_KEY_VERSION, someClass) + .setParameter(COL_NAME, key.getName()) + .setParameter(COL_VERSION, key.getVersion()) + .executeUpdate(); } mg.getTransaction().commit(); } finally { @@ -260,9 +276,11 @@ public class DefaultApexDao implements ApexDao { deletedCount += mg.createQuery( DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME - + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION - + key.getParentKeyVersion() + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", - someClass).executeUpdate(); + + AND_C_KEY_PARENT_KEY_VERSION + AND_C_KEY_LOCAL_NAME, someClass) + .setParameter(COL_PARENT_NAME, key.getParentKeyName()) + .setParameter(COL_PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(COL_LOCALNAME, key.getLocalName()) + .executeUpdate(); } mg.getTransaction().commit(); } finally { @@ -372,8 +390,9 @@ public class DefaultApexDao implements ApexDao { return mg .createQuery( SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME - + parentKey.getName() + AND_C_KEY_PARENT_KEY_VERSION + parentKey.getVersion() + "'", - someClass) + + AND_C_KEY_PARENT_KEY_VERSION, someClass) + .setParameter(COL_PARENT_NAME, parentKey.getName()) + .setParameter(COL_PARENT_VERSION, parentKey.getVersion()) .getResultList(); } finally { mg.close(); @@ -391,8 +410,11 @@ public class DefaultApexDao implements ApexDao { final EntityManager mg = getEntityManager(); List ret; try { - ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() - + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).getResultList(); + ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + + AND_C_KEY_VERSION, someClass) + .setParameter(COL_NAME, key.getName()) + .setParameter(COL_VERSION, key.getVersion()) + .getResultList(); } finally { mg.close(); } @@ -418,8 +440,11 @@ public class DefaultApexDao implements ApexDao { List ret; try { ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME - + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() - + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList(); + + AND_C_KEY_PARENT_KEY_VERSION + AND_C_KEY_LOCAL_NAME, someClass) + .setParameter(COL_PARENT_NAME, key.getParentKeyName()) + .setParameter(COL_PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(COL_LOCALNAME, key.getLocalName()) + .getResultList(); } finally { mg.close(); } diff --git a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java index 39eacce30..db7360e75 100644 --- a/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java +++ b/model/basic-model/src/main/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReader.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019-2020 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +62,7 @@ public class ApexModelReader { // (starts with private static final String XML_INPUT_TYPE_REGEXP = "^\\s*<\\?xml.*>\\s*"; // starts with some kind of bracket [ or ( - private static final String JSON_INPUT_TYPE_REGEXP = "^\\s*[\\(\\{\\[][\\s+\\S]*[\\)\\}\\]]"; + private static final String JSON_INPUT_TYPE_REGEXP = "^\\s*[\\(\\{\\[][\\s\\S]*[\\)\\}\\]]"; // or {, then has something, then has // and has a close bracket diff --git a/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java b/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java index 92f6206bb..d75f20253 100644 --- a/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java +++ b/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelReaderTest.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,12 +40,15 @@ import javax.xml.bind.PropertyException; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.model.basicmodel.concepts.AxModel; +@RunWith(MockitoJUnitRunner.class) public class ApexModelReaderTest { @Mock private Unmarshaller unmarshallerMock; diff --git a/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java b/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java index fbbe2467c..147eb206a 100644 --- a/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java +++ b/model/basic-model/src/test/java/org/onap/policy/apex/model/basicmodel/handling/ApexModelWriterTest.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2020 Nordix Foundation + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,13 +35,16 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.PropertyException; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.model.basicmodel.concepts.AxModel; import org.w3c.dom.Document; +@RunWith(MockitoJUnitRunner.class) public class ApexModelWriterTest { @Mock private Marshaller marshallerMock; diff --git a/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java b/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java index 7e15003a0..629e2556c 100644 --- a/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java +++ b/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextAlbum.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,6 @@ package org.onap.policy.apex.model.contextmodel.concepts; import java.util.List; import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; @@ -101,10 +101,8 @@ public class AxContextAlbum extends AxConcept { // @formatter:off @Embedded - @AttributeOverrides({ - @AttributeOverride(name = "name", column = @Column(name = "itemSchemaName")), - @AttributeOverride(name = "version", column = @Column(name = "itemSchemaVersion")) - }) + @AttributeOverride(name = "name", column = @Column(name = "itemSchemaName")) + @AttributeOverride(name = "version", column = @Column(name = "itemSchemaVersion")) @Column(name = "itemSchema") @XmlElement(name = "itemSchema", required = true) private AxArtifactKey itemSchema; diff --git a/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java b/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java index da04aad83..9fbcc81cb 100644 --- a/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java +++ b/model/context-model/src/main/java/org/onap/policy/apex/model/contextmodel/concepts/AxContextModel.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,6 @@ import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; @@ -64,18 +64,14 @@ public class AxContextModel extends AxModel { // @formatter:off @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({ - @JoinColumn(name = "schemasName", referencedColumnName = "name"), - @JoinColumn(name = "schemasVersion", referencedColumnName = "version") - }) + @JoinColumn(name = "schemasName", referencedColumnName = "name") + @JoinColumn(name = "schemasVersion", referencedColumnName = "version") @XmlElement(name = "schemas", required = true) private AxContextSchemas schemas; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({ - @JoinColumn(name = "albumsName", referencedColumnName = "name"), - @JoinColumn(name = "albumsVersion", referencedColumnName = "version") - }) + @JoinColumn(name = "albumsName", referencedColumnName = "name") + @JoinColumn(name = "albumsVersion", referencedColumnName = "version") @XmlElement(name = "albums", required = true) private AxContextAlbums albums; // @formatter:on diff --git a/model/engine-model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java b/model/engine-model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java index 3524f1290..23310b219 100644 --- a/model/engine-model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java +++ b/model/engine-model/src/main/java/org/onap/policy/apex/model/enginemodel/concepts/AxEngineModel.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +28,6 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Enumerated; import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -77,18 +77,14 @@ public class AxEngineModel extends AxContextModel { @XmlElement(required = true) private AxEngineState state; - // @formatter:off - @JoinColumns({ - @JoinColumn(name = "statsParentKeyName", referencedColumnName = "parentKeyName", updatable = false, - insertable = false), - @JoinColumn(name = "statsParentKeyVersion", referencedColumnName = "parentKeyVersion", updatable = false, - insertable = false), - @JoinColumn(name = "statsParentLocalName ", referencedColumnName = "parentLocalName", updatable = false, - insertable = false), - @JoinColumn(name = "statsLocalName", referencedColumnName = "localName", updatable = false, - insertable = false)}) + @JoinColumn(name = "statsParentKeyName", referencedColumnName = "parentKeyName", updatable = false, + insertable = false) + @JoinColumn(name = "statsParentKeyVersion", referencedColumnName = "parentKeyVersion", updatable = false, + insertable = false) + @JoinColumn(name = "statsParentLocalName ", referencedColumnName = "parentLocalName", updatable = false, + insertable = false) + @JoinColumn(name = "statsLocalName", referencedColumnName = "localName", updatable = false, insertable = false) private AxEngineStats stats; - // @formatter:on /** * The Default Constructor creates an engine model with a null key and all its fields undefined. diff --git a/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java b/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java index f4938dcea..511d4f3d0 100644 --- a/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java +++ b/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxEventModel.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,6 @@ import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.xml.bind.annotation.XmlAccessType; @@ -64,14 +64,14 @@ public class AxEventModel extends AxModel { // @formatter:off @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({ @JoinColumn(name = "schemasName", referencedColumnName = "name"), - @JoinColumn(name = "schemasVersion", referencedColumnName = "version") }) + @JoinColumn(name = "schemasName", referencedColumnName = "name") + @JoinColumn(name = "schemasVersion", referencedColumnName = "version") @XmlElement(name = "schemas", required = true) private AxContextSchemas schemas; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({ @JoinColumn(name = "eventsName", referencedColumnName = "name"), - @JoinColumn(name = "eventsVersion", referencedColumnName = "version") }) + @JoinColumn(name = "eventsName", referencedColumnName = "name") + @JoinColumn(name = "eventsVersion", referencedColumnName = "version") @XmlElement(name = "events", required = true) private AxEvents events; // @formatter:on diff --git a/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java b/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java index a1d6a8ba1..654a83ced 100644 --- a/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java +++ b/model/event-model/src/main/java/org/onap/policy/apex/model/eventmodel/concepts/AxField.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,6 @@ package org.onap.policy.apex.model.eventmodel.concepts; import java.util.List; import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; @@ -83,8 +83,8 @@ public class AxField extends AxConcept { // @formatter:off @Embedded - @AttributeOverrides({ @AttributeOverride(name = "name", column = @Column(name = "fieldSchemaName")), - @AttributeOverride(name = "version", column = @Column(name = "fieldSchemaVersion")) }) + @AttributeOverride(name = "name", column = @Column(name = "fieldSchemaName")) + @AttributeOverride(name = "version", column = @Column(name = "fieldSchemaVersion")) @Column(name = "fieldSchemaKey") @XmlElement(required = true) private AxArtifactKey fieldSchemaKey; diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java index 7b7dba800..d55fbd329 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +29,6 @@ import java.util.TreeSet; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.JoinColumn; -import javax.persistence.JoinColumns; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.xml.bind.Marshaller; @@ -120,33 +120,33 @@ public class AxPolicyModel extends AxModel { // @formatter:off @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({@JoinColumn(name = "policiesName", referencedColumnName = "name"), - @JoinColumn(name = "policiesVersion", referencedColumnName = "version")}) + @JoinColumn(name = "policiesName", referencedColumnName = "name") + @JoinColumn(name = "policiesVersion", referencedColumnName = "version") @XmlElement(name = "policies", required = true) private AxPolicies policies; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({@JoinColumn(name = "tasksName", referencedColumnName = "name"), - @JoinColumn(name = "tasksVersion", referencedColumnName = "version")}) + @JoinColumn(name = "tasksName", referencedColumnName = "name") + @JoinColumn(name = "tasksVersion", referencedColumnName = "version") @XmlElement(name = "tasks", required = true) private AxTasks tasks; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({@JoinColumn(name = "eventsName", referencedColumnName = "name"), - @JoinColumn(name = "eventsVersion", referencedColumnName = "version")}) + @JoinColumn(name = "eventsName", referencedColumnName = "name") + @JoinColumn(name = "eventsVersion", referencedColumnName = "version") @XmlElement(name = "events", required = true) private AxEvents events; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({@JoinColumn(name = "albumsName", referencedColumnName = "name"), - @JoinColumn(name = "albumsVersion", referencedColumnName = "version")}) + @JoinColumn(name = "albumsName", referencedColumnName = "name") + @JoinColumn(name = "albumsVersion", referencedColumnName = "version") @XmlElement(name = "albums", required = false) @XmlJavaTypeAdapter(EmptyAlbumsAdapter.class) private AxContextAlbums albums; @OneToOne(cascade = CascadeType.ALL) - @JoinColumns({@JoinColumn(name = "schemasName", referencedColumnName = "name"), - @JoinColumn(name = "schemasVersion", referencedColumnName = "version")}) + @JoinColumn(name = "schemasName", referencedColumnName = "name") + @JoinColumn(name = "schemasVersion", referencedColumnName = "version") @XmlElement(name = "schemas", required = true) private AxContextSchemas schemas; // @formatter:on @@ -749,4 +749,4 @@ public class AxPolicyModel extends AxModel { } return schemas.compareTo(other.schemas); } -} \ No newline at end of file +} diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java index 44b71f84a..80e967fdf 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java @@ -3,6 +3,7 @@ * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. * Modifications Copyright (C) 2019-2020 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +30,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; @@ -140,8 +140,8 @@ public class AxState extends AxConcept { // @formatter:off @Embedded - @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "inTriggerName")), - @AttributeOverride(name = "version", column = @Column(name = "inTriggerVersion"))}) + @AttributeOverride(name = "name", column = @Column(name = "inTriggerName")) + @AttributeOverride(name = "version", column = @Column(name = "inTriggerVersion")) @Column(name = "trigger") @XmlElement(required = true) private AxArtifactKey trigger; @@ -195,8 +195,8 @@ public class AxState extends AxConcept { private Map stateFinalizerLogicMap; @Embedded - @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "defaultTaskName")), - @AttributeOverride(name = "version", column = @Column(name = "defaultTaskVersion"))}) + @AttributeOverride(name = "name", column = @Column(name = "defaultTaskName")) + @AttributeOverride(name = "version", column = @Column(name = "defaultTaskVersion")) @Column(name = "defaultTask") @XmlElement(required = true) private AxArtifactKey defaultTask; diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java index 87caf03a2..27c187356 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,6 @@ package org.onap.policy.apex.model.policymodel.concepts; import java.util.List; import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; @@ -79,17 +79,17 @@ public class AxStateOutput extends AxConcept { // @formatter:off @Embedded - @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "outgoingEventName")), - @AttributeOverride(name = "version", column = @Column(name = "outgoingEventVersion"))}) + @AttributeOverride(name = "name", column = @Column(name = "outgoingEventName")) + @AttributeOverride(name = "version", column = @Column(name = "outgoingEventVersion")) @Column(name = "outgoingEvent") @XmlElement(required = true) private AxArtifactKey outgoingEvent; @Embedded - @AttributeOverrides({@AttributeOverride(name = "parentKeyName", column = @Column(name = "nextStateParentKeyName")), - @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "nextStateParentKeyVersion")), - @AttributeOverride(name = "parentLocalName", column = @Column(name = "nextStateParentLocalName")), - @AttributeOverride(name = "localName", column = @Column(name = "nextStateLocalName"))}) + @AttributeOverride(name = "parentKeyName", column = @Column(name = "nextStateParentKeyName")) + @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "nextStateParentKeyVersion")) + @AttributeOverride(name = "parentLocalName", column = @Column(name = "nextStateParentLocalName")) + @AttributeOverride(name = "localName", column = @Column(name = "nextStateLocalName")) @Column(name = "nextState") @XmlElement(required = true) private AxReferenceKey nextState; diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java index a3cb9e647..c98e38fbf 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,6 @@ package org.onap.policy.apex.model.policymodel.concepts; import java.util.List; import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; @@ -91,10 +91,10 @@ public class AxStateTaskReference extends AxConcept { // @formatter:off @Embedded - @AttributeOverrides({@AttributeOverride(name = "parentKeyName", column = @Column(name = "outputParentKeyName")), - @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "outputParentKeyVersion")), - @AttributeOverride(name = "parentLocalName", column = @Column(name = "outputParentLocalName")), - @AttributeOverride(name = "localName", column = @Column(name = "outputLocalName"))}) + @AttributeOverride(name = "parentKeyName", column = @Column(name = "outputParentKeyName")) + @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "outputParentKeyVersion")) + @AttributeOverride(name = "parentLocalName", column = @Column(name = "outputParentLocalName")) + @AttributeOverride(name = "localName", column = @Column(name = "outputLocalName")) @Column(name = "output") @XmlElement(required = true) private AxReferenceKey output; diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java index cd21742a4..a27e1af1e 100644 --- a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java +++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2019 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +23,12 @@ package org.onap.policy.apex.model.policymodel.concepts; import java.util.ArrayList; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; +import lombok.EqualsAndHashCode; import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; import org.onap.policy.common.utils.validation.Assertions; @@ -38,6 +41,7 @@ import org.onap.policy.common.utils.validation.Assertions; *

Validation checks for recursive state use, in other words validation forbids the use of a given * state more than once in a state tree. */ +@EqualsAndHashCode public class AxStateTree implements Comparable { private final AxState thisState; private final Set nextStates; @@ -144,12 +148,26 @@ public class AxStateTree implements Comparable { } final AxStateTree other = otherObj; - if (!thisState.equals(other.thisState)) { - return thisState.compareTo(other.thisState); + int result = thisState.compareTo(other.thisState); + if (result != 0) { + return result; } - if (!nextStates.equals(other.nextStates)) { - return (nextStates.hashCode() - other.nextStates.hashCode()); + + result = Integer.compare(nextStates.size(), other.nextStates.size()); + if (result != 0) { + return result; + } + + Iterator iter1 = nextStates.iterator(); + Iterator iter2 = other.nextStates.iterator(); + + while (iter1.hasNext()) { + result = iter1.next().compareTo(iter2.next()); + if (result != 0) { + return result; + } } + return 0; } } 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 index 0d90d8ceb..190b270ea 100644 --- 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 @@ -1,19 +1,20 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT 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========================================================= */ @@ -28,7 +29,7 @@ import java.util.ListIterator; * * @author Liam Fallon (liam.fallon@ericsson.com) */ -public abstract class CollectionUtils { +public class CollectionUtils { /** * Private constructor used to prevent sub class instantiation. */ 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 index 4f43e6c4d..d48f7f951 100644 --- 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 @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,7 @@ import java.util.NavigableMap; * * @author Liam Fallon (liam.fallon@ericsson.com) */ -public abstract class TreeMapUtils { +public class TreeMapUtils { /** * This class is a utility class that can't be instantiated. -- cgit 1.2.3-korg