All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.annotation.ReferencePath Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.NavigableSet;
import java.util.Optional;

/**
 * Annotates Java instance methods that should return all objects found at the far end of a reference path,
 * starting from the current instance.
 *
 * 
 * 
 * 
 *
 * 

* This annotation can be used as a convenience to let Permazen auto-generate {@link io.permazen.ReferencePath} traversal code. * A common use case is inverting references, e.g., from a parent back to a child in a one-to-many relationship. * *

* Annotating an abstract method with {@code @ReferencePath("->some->path")} is equivalent to providing an implementation * that returns all objects reachable via the {@linkplain io.permazen.ReferencePath reference path} {@code "->some->path"} when * starting at the current instance. References can be traversed in either the forward or inverse directions; see * {@link io.permazen.ReferencePath} for details on reference paths. * *

* For example: *


 *  @PermazenType
 *  public interface TreeNode extends PermazenObject {
 *
 *      /**
 *       * Get the parent of this node, or null if node is a root.
 *       */
 *      TreeNode getParent();
 *      void setParent(TreeNode parent);
 *
 *      /**
 *       * Get the children of this node.
 *       */
 *      @ReferencePath("<-TreeNode.parent")
 *      NavigableSet<TreeNode> getChildren();
 *
 *      /**
 *       * Get this node's grandparent, if any.
 *       */
 *      @ReferencePath("->parent->parent")
 *      Optional<TreeNode> getGrandparent();
 *  }
 * 
* In the example above, the generated {@code getChildren()} implementation will be functionally equivalent to * (and slightly more efficient than) this one: *

 *      /**
 *       * Get the children of this node.
 *       */
 *      NavigableSet<TreeNode> getChildren() {
 *          final PermazenTransaction jtx = this.getTransaction();
 *          final ReferencePath path = jtx.getPermazen().parseReferencePath(this.getClass(), "<-TreeNode.parent");
 *          return jtx.followReferencePath(path, Collections.singleton(this));
 *      }
 *  }
 * 
* *

Method Return Type

* *

* The annotated method must be an instance method and return either {@link NavigableSet NavigableSet<T>} * or {@link Optional}{@code }, where {@code T} is any super-type of the target object type(s) at the end * of the reference path. * *

* If the reference path {@link io.permazen.ReferencePath#isSingular isSingular()} (i.e., contains only forward traversals * of simple reference fields), then only one object can be returned and the return type must be {@link Optional}{@code }. * *

* Otherwise, either return type is valid, and you can use {@link Optional}{@code } if you only care to * retrieve at most a single instance. * *

* More examples: *


 *  @PermazenType
 *  public interface TreeNode extends PermazenObject {
 *
 *      /**
 *       * Get the parent of this node, or null if node is a root.
 *       */
 *      TreeNode getParent();
 *      void setParent(TreeNode parent);
 *
 *      /**
 *       * Get the children of this node.
 *       */
 *      @ReferencePath("<-TreeNode.parent")
 *      NavigableSet<TreeNode> getChildren();
 *
 *      /**
 *       * Get the siblings of this node (including this node).
 *       */
 *      @ReferencePath("->parent<-TreeNode.parent")
 *      NavigableSet<TreeNode> getSiblings();
 *
 *      /**
 *       * Get second cousins once removed (and parents), but only the first.
 *       */
 *      @ReferencePath("->parent->parent->parent<-TreeNode.parent<-TreeNode.parent")
 *      Optional<TreeNode> getSecondCousinOnceRemoved();
 *  }
 * 
* *

Meta-Annotations

* *

* This annotation may be configured indirectly as a Spring * meta-annotation * when {@code spring-core} is on the classpath. * * @see io.permazen.ReferencePath */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD }) @Documented public @interface ReferencePath { /** * The reference path to follow. * *

* The starting type for the reference path is the class containing the annotated method. * * @return the reference path to traverse * @see io.permazen.ReferencePath */ String value() default ""; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy