/** * Parse a {@link ReferencePath}. * * @param startType starting Java type for the path * @param path dot-separated path of zero or more reference fields, followed by an optional target field * @param expectTargetField true if {@code path} contains a target field, false otherwise * @return parsed reference path * @throws IllegalArgumentException if {@code path} is invalid * @throws IllegalArgumentException if {@code startType} or {@code path} is null * @see ReferencePath */ public ReferencePath parseReferencePath(Class<?> startType, String path, boolean expectTargetField) { return this.parseReferencePath(startType, path, expectTargetField, null); }
/** * Parse a {@link ReferencePath} containing a target field. * * <p> * Equivalent to: {@link #parseReferencePath(Class, String, boolean) parseReferencePath}{@code (startType, path, true)}. * * @param startType starting Java type for the path * @param path dot-separated path of zero or more reference fields, followed by a target field * @return parsed reference path * @throws IllegalArgumentException if {@code path} is invalid * @throws IllegalArgumentException if {@code startType} or {@code path} is null * @see ReferencePath */ public ReferencePath parseReferencePath(Class<?> startType, String path) { return this.parseReferencePath(startType, path, true); }
/** * Get the {@code byte[]} key in the underlying key/value store corresponding to the specified field in the specified object. * * <p> * Notes: * <ul> * <li>Complex fields utilize mutiple keys; the return value is the common prefix of all such keys.</li> * <li>The {@link io.permazen.kv.KVDatabase} should not be modified directly, otherwise behavior is undefined</li> * </ul> * * @param jobj Java model object * @param fieldName the name of a field in {@code jobj}'s type * @return the {@link io.permazen.kv.KVDatabase} key of the field in the specified object * @throws TypeNotInSchemaVersionException if the current schema version does not contain the object's type * @throws IllegalArgumentException if {@code jobj} does not contain the specified field * @throws IllegalArgumentException if {@code fieldName} is otherwise invalid * @throws IllegalArgumentException if either parameter is null * @see io.permazen.kv.KVTransaction#watchKey KVTransaction.watchKey() * @see io.permazen.core.Transaction#getKey(ObjId, int) Transaction.getKey() */ public byte[] getKey(JObject jobj, String fieldName) { Preconditions.checkArgument(jobj != null, "null jobj"); final Class<?> type = this.jdb.getJClass(jobj.getObjId()).type; final ReferencePath refPath = this.jdb.parseReferencePath(type, fieldName, true, false); if (refPath.getReferenceFields().length > 0) throw new IllegalArgumentException("invalid field name `" + fieldName + "'"); assert refPath.getTargetTypes().iterator().next().isInstance(jobj); return this.tx.getKey(jobj.getObjId(), refPath.targetFieldStorageId); }
final ReferencePath path = jdb.parseReferencePath(this.startType, fieldName, true, true); if (path.getReferenceFields().length > 0) throw new IllegalArgumentException("invalid field name `" + fieldName + "': contains intermediate reference(s)");
final ReferencePath path = this.jdb.parseReferencePath(startType, refPath, false, true);