Skip to content

Commit

Permalink
interim commit
Browse files Browse the repository at this point in the history
  • Loading branch information
david-waltermire committed May 5, 2024
1 parent 9673a7b commit 7496fad
Show file tree
Hide file tree
Showing 36 changed files with 350 additions and 280 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Portions of this software was developed by employees of the National Institute
* of Standards and Technology (NIST), an agency of the Federal Government and is
* being made available as a public service. Pursuant to title 17 United States
* Code Section 105, works of NIST employees are not subject to copyright
* protection in the United States. This software may be subject to foreign
* copyright. Permission in the United States and in foreign countries, to the
* extent that NIST may hold copyright, to use, copy, modify, create derivative
* works, and distribute this software and its documentation without fee is hereby
* granted on a non-exclusive basis, provided that this notice and disclaimer
* of warranty appears in all copies.
*
* THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
* EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
* THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
* INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
* SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT
* SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
* INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
* OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
* CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
* PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
* OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
*/

package gov.nist.secauto.metaschema.core.model;

import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import javax.xml.namespace.QName;

import edu.umd.cs.findbugs.annotations.NonNull;
import nl.talsmasoftware.lazy4j.Lazy;

public abstract class AbstractDefinition
implements IDefinition {
@NonNull
private final Lazy<QName> qname;
@NonNull
private final Lazy<QName> definitionQName;

protected AbstractDefinition(@NonNull NameInitializer initializer) {
this.qname = ObjectUtils.notNull(Lazy.lazy(() -> initializer.apply(getEffectiveName())));
this.definitionQName = ObjectUtils.notNull(Lazy.lazy(() -> initializer.apply(getName())));
}

@SuppressWarnings("null")
@Override
public final QName getXmlQName() {
return qname.get();
}

@SuppressWarnings("null")
@Override
public final QName getDefinitionQName() {
return definitionQName.get();
}

@FunctionalInterface
public interface NameInitializer {
@NonNull
QName apply(@NonNull String name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,16 @@

package gov.nist.secauto.metaschema.core.model;

import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import javax.xml.namespace.QName;

import edu.umd.cs.findbugs.annotations.NonNull;
import nl.talsmasoftware.lazy4j.Lazy;

public abstract class AbstractGlobalDefinition<MODULE extends IModule, INSTANCE extends INamedInstance>
implements IDefinition {
extends AbstractDefinition {
@NonNull
private final MODULE module;
@NonNull
private final Lazy<QName> qname;
@NonNull
private final Lazy<QName> definitionQName;

protected AbstractGlobalDefinition(@NonNull MODULE module, @NonNull NameInitializer initializer) {
super(initializer);
this.module = module;
this.qname = ObjectUtils.notNull(Lazy.lazy(() -> initializer.apply(getEffectiveName())));
this.definitionQName = ObjectUtils.notNull(Lazy.lazy(() -> initializer.apply(getName())));
}

@SuppressWarnings("null")
@Override
public final QName getXmlQName() {
return qname.get();
}

@SuppressWarnings("null")
@Override
public final QName getDefinitionQName() {
return definitionQName.get();
}

@Override
Expand All @@ -76,10 +54,4 @@ public final INSTANCE getInlineInstance() {
// never inline
return null;
}

@FunctionalInterface
public interface NameInitializer {
@NonNull
QName apply(@NonNull String name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

package gov.nist.secauto.metaschema.core.model;

import gov.nist.secauto.metaschema.core.model.AbstractGlobalDefinition.NameInitializer;
import gov.nist.secauto.metaschema.core.model.AbstractDefinition.NameInitializer;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;

import javax.xml.namespace.QName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@

package gov.nist.secauto.metaschema.databind.model;

import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.io.BindingException;
import gov.nist.secauto.metaschema.databind.model.info.IFeatureComplexItemValueHandler;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.function.Predicate;

Expand All @@ -42,4 +47,102 @@ public interface IBoundDefinitionModelComplex

@NonNull
Map<String, IBoundProperty> getJsonProperties(@Nullable Predicate<IBoundInstanceFlag> flagFilter);

@Override
default boolean isInline() {
return getBoundClass().getEnclosingClass() != null;
}

/**
* Gets a new instance of the bound class.
*
* @param <CLASS>
* the type of the bound class
* @return a Java object for the class
* @throws RuntimeException
* if the instance cannot be created due to a binding error
*/
@SuppressWarnings("PMD.AvoidThrowingRawExceptionTypes")
@Override
@NonNull
default <CLASS> CLASS newInstance() {
Class<?> clazz = getBoundClass();
try {
@SuppressWarnings("unchecked") Constructor<CLASS> constructor
= (Constructor<CLASS>) clazz.getDeclaredConstructor();
return ObjectUtils.notNull(constructor.newInstance());
} catch (NoSuchMethodException ex) {
String msg = String.format("Class '%s' does not have a required no-arg constructor.", clazz.getName());
throw new RuntimeException(msg, ex);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}

@Nullable
Method getBeforeDeserializeMethod();

/**
* Calls the method named "beforeDeserialize" on each class in the object's
* hierarchy if the method exists on the class.
* <p>
* These methods can be used to set the initial state of the target bound object
* before data is read and applied during deserialization.
*
* @param targetObject
* the data object target to call the method(s) on
* @param parentObject
* the object target's parent object, which is used as the method
* argument
* @throws BindingException
* if an error occurs while calling the method
*/
@Override
default void callBeforeDeserialize(Object targetObject, Object parentObject) throws BindingException {
Method beforeDeserializeMethod = getBeforeDeserializeMethod();
if (beforeDeserializeMethod != null) {
try {
beforeDeserializeMethod.invoke(targetObject, parentObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new BindingException(ex);
}
}
}

@Nullable
Method getAfterDeserializeMethod();

/**
* Calls the method named "afterDeserialize" on each class in the object's
* hierarchy if the method exists.
* <p>
* These methods can be used to modify the state of the target bound object
* after data is read and applied during deserialization.
*
* @param targetObject
* the data object target to call the method(s) on
* @param parentObject
* the object target's parent object, which is used as the method
* argument
* @throws BindingException
* if an error occurs while calling the method
*/
@Override
default void callAfterDeserialize(Object targetObject, Object parentObject) throws BindingException {
Method afterDeserializeMethod = getAfterDeserializeMethod();
if (afterDeserializeMethod != null) {
try {
afterDeserializeMethod.invoke(targetObject, parentObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new BindingException(ex);
}
}
}

// @Override
// public String getJsonKeyFlagName() {
// // definition items never have a JSON key
// return null;
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
import gov.nist.secauto.metaschema.databind.model.IFeatureBoundContainerFlag;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.xml.namespace.QName;

import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import nl.talsmasoftware.lazy4j.Lazy;
Expand All @@ -53,6 +53,10 @@ public abstract class AbstractBoundDefinitionModelComplex<A extends Annotation>
private final IBindingContext bindingContext;
@NonNull
private final Lazy<IBoundModule> module;
@NonNull
private final Lazy<QName> qname;
@NonNull
private final Lazy<QName> definitionQName;
@Nullable
private final Method beforeDeserializeMethod;
@Nullable
Expand All @@ -67,6 +71,8 @@ protected AbstractBoundDefinitionModelComplex(
this.annotation = annotation;
this.bindingContext = bindingContext;
this.module = ObjectUtils.notNull(Lazy.lazy(() -> bindingContext.registerModule(moduleClass)));
this.qname = ObjectUtils.notNull(Lazy.lazy(() -> getContainingModule().toModelQName(getEffectiveName())));
this.definitionQName = ObjectUtils.notNull(Lazy.lazy(() -> getContainingModule().toModelQName(getName())));
this.beforeDeserializeMethod = ClassIntrospector.getMatchingMethod(
clazz,
"beforeDeserialize",
Expand All @@ -86,11 +92,6 @@ public A getAnnotation() {
return annotation;
}

@Override
public boolean isInline() {
return getBoundClass().getEnclosingClass() != null;
}

@Override
@NonNull
public IBoundModule getContainingModule() {
Expand All @@ -103,82 +104,31 @@ public IBindingContext getBindingContext() {
return bindingContext;
}

/**
* Gets a new instance of the bound class.
*
* @param <CLASS>
* the type of the bound class
* @return a Java object for the class
* @throws RuntimeException
* if the instance cannot be created due to a binding error
*/
@SuppressWarnings("PMD.AvoidThrowingRawExceptionTypes")
@SuppressWarnings("null")
@Override
@NonNull
public <CLASS> CLASS newInstance() {
Class<?> clazz = getBoundClass();
try {
@SuppressWarnings("unchecked") Constructor<CLASS> constructor
= (Constructor<CLASS>) clazz.getDeclaredConstructor();
return ObjectUtils.notNull(constructor.newInstance());
} catch (NoSuchMethodException ex) {
String msg = String.format("Class '%s' does not have a required no-arg constructor.", clazz.getName());
throw new RuntimeException(msg, ex);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
public final QName getXmlQName() {
return qname.get();
}

/**
* Calls the method named "beforeDeserialize" on each class in the object's
* hierarchy if the method exists on the class.
* <p>
* These methods can be used to set the initial state of the target bound object
* before data is read and applied during deserialization.
*
* @param targetObject
* the data object target to call the method(s) on
* @param parentObject
* the object target's parent object, which is used as the method
* argument
* @throws BindingException
* if an error occurs while calling the method
*/
@SuppressWarnings("null")
@Override
public void callBeforeDeserialize(Object targetObject, Object parentObject) throws BindingException {
if (beforeDeserializeMethod != null) {
try {
beforeDeserializeMethod.invoke(targetObject, parentObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new BindingException(ex);
}
}
public final QName getDefinitionQName() {
return definitionQName.get();
}

/**
* Calls the method named "afterDeserialize" on each class in the object's
* hierarchy if the method exists.
* <p>
* These methods can be used to modify the state of the target bound object
* after data is read and applied during deserialization.
*
* @param targetObject
* the data object target to call the method(s) on
* @param parentObject
* the object target's parent object, which is used as the method
* argument
* @throws BindingException
* if an error occurs while calling the method
*/
@Override
public void callAfterDeserialize(Object targetObject, Object parentObject) throws BindingException {
if (afterDeserializeMethod != null) {
try {
afterDeserializeMethod.invoke(targetObject, parentObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new BindingException(ex);
}
}
public boolean isInline() {
return getBoundClass().getEnclosingClass() != null;
}

@Override
public Method getBeforeDeserializeMethod() {
return beforeDeserializeMethod;
}

@Override
public Method getAfterDeserializeMethod() {
return afterDeserializeMethod;
}

// @Override
Expand Down
Loading

0 comments on commit 7496fad

Please sign in to comment.