/** * Create a new instance of the given model class in this transaction. * * @param type Java object model type * @param <T> Java model type * @return newly created instance * @throws IllegalArgumentException if {@code type} is not a known Java object model type * @throws StaleTransactionException if this transaction is no longer usable */ public <T> T create(Class<T> type) { return this.create(this.jdb.getJClass(type)); }
final SchemaObjectType schemaType = ReferencePath.this.jdb.getNameIndex().getSchemaObjectType(typeName); if (schemaType != null) type = ReferencePath.this.jdb.getJClass(schemaType.getStorageId()).getType(); else { try {
/** * Get the {@link JClass} corresponding to the currently selected type, if any. * * @return selected type object type */ public JClass<?> getJClass() { final Class<?> type = this.objectContainer.getType(); if (type == null) return null; try { return this.jdb.getJClass(type); } catch (IllegalArgumentException e) { return null; } }
/** * Constructor. * * <p> * Uses a default {@code objectMapper} that creates new exported objects using the default constructor of the model class. * * @param jtx the transaction from which to export objects * @throws IllegalArgumentException if {@code jtx} is null */ public ExportContext(JTransaction jtx) { Preconditions.checkArgument(jtx != null); this.jtx = jtx; this.objectMapper = id -> { final Class<?> type = this.jtx.jdb.getJClass(id).getType(); try { return type.newInstance(); } catch (Exception e) { throw new IllegalArgumentException("can't instatiate " + type + " using default constructor for POJO export", e); } }; }
private void recurseOnFields() { while (!this.needingFieldsCopied.isEmpty()) { // Remove the next object needing its fields copied final Iterator<Map.Entry<ObjId, Object>> i = this.needingFieldsCopied.entrySet().iterator(); final Map.Entry<ObjId, Object> entry = i.next(); final ObjId id = entry.getKey(); final Object obj = entry.getValue(); i.remove(); // Copy fields for (JField jfield : this.jtx.jdb.getJClass(id).jfields.values()) jfield.exportPlain(this, id, obj); } }
private void recurseOnFields() { while (!this.needingFieldsCopied.isEmpty()) { // Remove the next object needing its fields copied final Iterator<Map.Entry<Object, ObjId>> i = this.needingFieldsCopied.entrySet().iterator(); final Map.Entry<Object, ObjId> entry = i.next(); final Object obj = entry.getKey(); final ObjId id = entry.getValue(); i.remove(); // Copy fields for (JField jfield : this.jtx.jdb.getJClass(id).jfields.values()) jfield.importPlain(this, obj, id); } }
@Override public Class<?> getType(ParseSession session) { try { return session.getPermazen().getJClass(id).getType(); } catch (TypeNotInSchemaVersionException e) { return UntypedJObject.class; } catch (IllegalArgumentException e) { return Object.class; } } };
private JField getJField(final JObject jobj) { return JObjectContainer.this.jdb.getJClass(jobj.getObjId()).getJField(this.storageId, JField.class); }
/** * Get the {@link JClass} of which this {@link JObject} is an instance. * * @return associated {@link JClass} * @throws io.permazen.core.TypeNotInSchemaVersionException if this instance has a type that does not exist * in this instance's schema version, i.e., this instance is an {@link UntypedJObject} */ default JClass<?> getJClass() { return this.getTransaction().getPermazen().getJClass(this.getObjId()); }
for (JField jfield : this.getJClass(id).getJFieldsByStorageId().values()) { jfield.visit(new JFieldSwitchAdapter<Void>() {
/** * 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); }
/** * Quick lookup for the {@link JField} corresponding to the given object and field storage ID. * * @param id object ID * @param storageId field storage ID * @param <T> expected field type * @return list of {@link JClass}es whose type is {@code type} or a sub-type, ordered by storage ID * @throws TypeNotInSchemaVersionException if {@code id} has a type that does not exist in this instance's schema version * @throws UnknownFieldException if {@code storageId} does not correspond to any field in the object's type */ @SuppressWarnings("unchecked") <T extends JField> T getJField(ObjId id, int storageId, Class<T> type) { final JField jfield = this.typeFieldMap.get(this.getTypeFieldKey(id.getStorageId(), storageId)); if (jfield == null) { this.getJClass(id.getStorageId()).getJField(storageId, type); // should always throw the appropriate exception assert false; } try { return type.cast(jfield); } catch (ClassCastException e) { throw new UnknownFieldException(storageId, jfield + "' is not a " + type.getSimpleName().replaceAll("^J(.*)Field$", "").toLowerCase() + " field"); } }
jclass = session.getPermazen().getJClass(objType.getStorageId()); } catch (UnknownTypeException e) { throw new IllegalArgumentException("error accessing field `" + name + "': " + e.getMessage(), e);
final Class<?> startType = this.jdb.getJClass(id).type; final ArrayList<int[]> pathReferencesList = new ArrayList<>(refPaths.length); for (String refPath : refPaths) {
private void doOnCreate(ObjId id) { // Get JClass, if known final JClass<?> jclass; try { jclass = this.jdb.getJClass(id); } catch (TypeNotInSchemaVersionException e) { return; // object type does not exist in our schema } // Enqueue for revalidation if (this.validationMode == ValidationMode.AUTOMATIC && jclass.requiresDefaultValidation) this.revalidate(Collections.singleton(id)); // Notify @OnCreate methods Object jobj = null; for (OnCreateScanner<?>.MethodInfo info : jclass.onCreateMethods) { if (this.isSnapshot() && !info.getAnnotation().snapshotTransactions()) continue; if (jobj == null) jobj = this.get(id); Util.invoke(info.getMethod(), jobj); } }
private void doOnDelete(ObjId id) { // Get JClass, if known final JClass<?> jclass; try { jclass = this.jdb.getJClass(id); } catch (TypeNotInSchemaVersionException e) { return; // object type does not exist in our schema } // Notify @OnDelete methods Object jobj = null; for (OnDeleteScanner<?>.MethodInfo info : jclass.onDeleteMethods) { if (this.isSnapshot() && !info.getAnnotation().snapshotTransactions()) continue; if (jobj == null) jobj = this.get(id); Util.invoke(info.getMethod(), jobj); } }
jclass = JTransaction.getCurrent().getPermazen().getJClass(storageId); } catch (UnknownTypeException e) { throw new EvalException(e.getMessage(), e);
private void editButtonClicked() { final ObjId id = this.objectChooser.getObjId(); if (id == null) return; this.log.info("editing object " + id); // Copy object final JObject jobj = this.doCopyForEdit(id); if (jobj == null) { Notification.show("Object " + id + " no longer exists", null, Notification.Type.WARNING_MESSAGE); return; } // Ensure object type is known if (jobj instanceof UntypedJObject) { Notification.show("Can't edit object " + id + " having unknown object type", "Storage ID " + id.getStorageId() + " not defined in the current schema version", Notification.Type.WARNING_MESSAGE); return; } // Build title component from reference label Object refLabel = MainPanel.this.objectChooser.getJObjectContainer().getContainerProperty( id, JObjectContainer.REFERENCE_LABEL_PROPERTY).getValue(); final Component titleComponent = refLabel instanceof Component ? (Component)refLabel : new Label("" + refLabel); // Open window final JObjectEditorWindow editor = new JObjectEditorWindow(this.getUI(), this.session, this.jdb.getJClass(id), jobj, titleComponent); editor.setReloadContainerAfterCommit(this.objectChooser.getJObjectContainer()); editor.show(); }
@Override public Object get(ParseSession session) { if (session.getMode().hasPermazen()) { final Class<?> type = param instanceof ObjType ? session.getPermazen().getJClass(((ObjType)param).getStorageId()).getType() : param instanceof Node ? ((Node)param).evaluate(session).checkType(session, QueryVersionFunction.this.getName(), Class.class) : Object.class; return JTransaction.getCurrent().queryVersion(type); } else { CoreIndex<Integer, ObjId> index = session.getTransaction().queryVersion(); final int storageId = param instanceof Node ? ((Node)param).evaluate(session).checkType(session, QueryVersionFunction.this.getName(), Integer.class) : param instanceof ObjType ? ((ObjType)param).getStorageId() : -1; if (storageId != -1) index = index.filter(1, new KeyRanges(ObjId.getKeyRange(storageId))); return index.asMap(); } } };
throw new ParseException(ctx); ctx.setIndex(mark); param1 = new LiteralNode(session.getPermazen().getJClass(objType.getStorageId()).getType()); } catch (ParseException e) { ctx.setIndex(typeStart);