/** * Compares this field path with the given field path, returns true if the field path starts with the other. * * @param other The field path to compare with. * @return Returns true if this field path starts with the other field path, otherwise false */ public boolean startsWith(FieldPath other) { if (other.size() > size()) { return false; } for (int i = 0; i < other.size(); i++) { if (!other.get(i).equals(get(i))) { return false; } } return true; }
@Override public FieldPath buildFieldPath(String remainFieldName) { if (remainFieldName.length() == 0) { return new FieldPath(); } String currFieldName = remainFieldName; String subFieldName = ""; for (int i = 0; i < remainFieldName.length(); i++) { if (remainFieldName.charAt(i) == '.') { currFieldName = remainFieldName.substring(0, i); subFieldName = remainFieldName.substring(i + 1); break; } else if (remainFieldName.charAt(i) == '{' || remainFieldName.charAt(i) == '[') { currFieldName = remainFieldName.substring(0, i); subFieldName = remainFieldName.substring(i); break; } } Field f = getField(currFieldName); if (f != null) { FieldPath fieldPath = f.getDataType().buildFieldPath(subFieldName); List<FieldPathEntry> tmpPath = new ArrayList<FieldPathEntry>(fieldPath.getList()); tmpPath.add(0, FieldPathEntry.newStructFieldEntry(f)); return new FieldPath(tmpPath); } else { throw new IllegalArgumentException("Field '" + currFieldName + "' not found in type " + this); } }
private FieldPath getFieldPath(String fieldName) { if (fieldMap != null && fieldMap.containsKey(fieldName)) { fieldName = fieldMap.get(fieldName); } checkAccess(new Field(fieldName)); FieldPath path = FieldPath.newInstance(getDataType(), fieldName); if (path == null || path.size() == 0) { throw new IllegalArgumentException("Malformed schema mapping '" + fieldName + "'."); } return path; }
@SuppressWarnings({ "unchecked", "rawtypes" }) private void createUpdatesAt(List<FieldPathEntry> path, FieldValue value, int idx, DocumentUpdate out) { FieldPath updatePath = update.getFieldPath(); if (idx < updatePath.size()) { FieldPathEntry pathEntry = updatePath.get(idx); FieldPathEntry.Type type = pathEntry.getType(); if (type == FieldPathEntry.Type.STRUCT_FIELD) { value.getClass().getName() + "."); out.addFieldPathUpdate(new AddFieldPathUpdate(update.getDocumentType(), new FieldPath(path).toString(), update.getOriginalWhereClause(), (Array)value)); } else if (update instanceof AssignFieldPathUpdate) { out.addFieldPathUpdate(new AssignFieldPathUpdate(update.getDocumentType(), new FieldPath(path).toString(), update.getOriginalWhereClause(), value)); } else if (update instanceof RemoveFieldPathUpdate) { out.addFieldPathUpdate(new RemoveFieldPathUpdate(update.getDocumentType(), new FieldPath(path).toString(), update.getOriginalWhereClause()));
@Override public DataType getInputType(Expression exp, String fieldName) { try { return input.getDataType().buildFieldPath(fieldName).getResultingDataType(); } catch (IllegalArgumentException e) { throw new VerificationException(exp, "Input field '" + fieldName + "' not found."); } }
/** * Iterates through the document using the given fieldpath, calling callbacks in the given iterator * handler. */ FieldPathIteratorHandler.ModificationStatus iterateNested(FieldPath fieldPath, int pos, FieldPathIteratorHandler handler) { if (pos >= fieldPath.size()) { handler.onPrimitive(this); return handler.modify(this); } else { throw new IllegalArgumentException("Primitive types can't be iterated through"); } }
/** * Creates a field path from the given field path string. * * @param fieldPathString a string containing the field path * @return Returns a valid field path, parsed from the string */ public FieldPath buildFieldPath(String fieldPathString) { if (fieldPathString.length() > 0) { throw new IllegalArgumentException("Datatype " + toString() + " does not support further recursive structure: " + fieldPathString); } return new FieldPath(); }
private void write(FieldPath fieldPath, Collection<FieldPathUpdate> fieldPathUpdates, JsonGenerator generator) throws IOException { generator.writeObjectFieldStart(fieldPath.toString()); for (FieldPathUpdate update : fieldPathUpdates) { if (writeArithmeticFieldPathUpdate(update, generator)) continue; generator.writeFieldName(update.getUpdateType().name().toLowerCase()); if (update instanceof AssignFieldPathUpdate) { AssignFieldPathUpdate assignUp = (AssignFieldPathUpdate) update; if (assignUp.getExpression() != null) { throw new RuntimeException("Unable to parse expression: " + assignUp.getExpression()); } else { assignUp.getNewValue().serialize(null, this); } } else if (update instanceof AddFieldPathUpdate) { ((AddFieldPathUpdate) update).getNewValues().serialize(null, this); } else if (update instanceof RemoveFieldPathUpdate) { generator.writeNumber(0); } else { throw new RuntimeException("Unsupported fieldpath operation: " + update.getClass().getName()); } } generator.writeEndObject(); }
private static Field resolveField(FieldPathUpdate update) { String orig = update.getOriginalFieldPath(); if (orig == null) { return null; } FieldPath path = update.getFieldPath(); if (path == null) { return null; } DataType type = path.getResultingDataType(); if (type == null) { return null; } return new Field(orig, type); } }
/** * note that the returned Field may not be in this Document * directly, but may refer to a field in a struct contained in it, * in which case the returned Field is only useful for obtaining * the field type; it can't be used for get() and set(). **/ @Override public Field getField(String fieldName) { if (fieldMap != null && fieldMap.containsKey(fieldName)) { fieldName = fieldMap.get(fieldName); } FieldPath path = getFieldPath(fieldName); Field ret = path.get(path.size() - 1).getFieldRef(); checkAccess(ret); return ret; }
public void read(AssignFieldPathUpdate update) { try { for (int i = 0; i < reader.getAttributeCount(); i++) { if (reader.getAttributeName(i).toString().equals("removeifzero")) { update.setRemoveIfZero(Boolean.parseBoolean(reader.getAttributeValue(i))); } else if (reader.getAttributeName(i).toString().equals("createmissingpath")) { update.setCreateMissingPath(Boolean.parseBoolean(reader.getAttributeValue(i))); } } DataType dt = update.getFieldPath().getResultingDataType(); if (dt instanceof NumericDataType) { update.setExpression(reader.getElementText()); } else { FieldValue fv = dt.createFieldValue(); fv.deserialize(resolveField(update), this); update.setNewValue(fv); } } catch (XMLStreamException e) { throw newException(e); } }
public static FieldPath buildFieldPath(String remainFieldName, DataType keyType, DataType valueType) { if (remainFieldName.length() > 0 && remainFieldName.charAt(0) == '{') { FieldPathEntry.KeyParseResult result = FieldPathEntry.parseKey(remainFieldName); String keyValue = result.parsed; FieldPath path = valueType.buildFieldPath(skipDotInString(remainFieldName, result.consumedChars - 1)); List<FieldPathEntry> tmpPath = new ArrayList<FieldPathEntry>(path.getList()); if (remainFieldName.charAt(1) == '$') { tmpPath.add(0, FieldPathEntry.newVariableLookupEntry(keyValue.substring(1), valueType)); } else { FieldValue fv = keyType.createFieldValue(); fv.assign(keyValue); tmpPath.add(0, FieldPathEntry.newMapLookupEntry(fv, valueType)); } return new FieldPath(tmpPath); } else if (remainFieldName.startsWith("key")) { FieldPath path = keyType.buildFieldPath(skipDotInString(remainFieldName, 2)); List<FieldPathEntry> tmpPath = new ArrayList<FieldPathEntry>(path.getList()); tmpPath.add(0, FieldPathEntry.newAllKeysLookupEntry(keyType)); return new FieldPath(tmpPath); } else if (remainFieldName.startsWith("value")) { FieldPath path = valueType.buildFieldPath(skipDotInString(remainFieldName, 4)); List<FieldPathEntry> tmpPath = new ArrayList<FieldPathEntry>(path.getList()); tmpPath.add(0, FieldPathEntry.newAllValuesLookupEntry(valueType)); return new FieldPath(tmpPath); } return keyType.buildFieldPath(remainFieldName); }
public static boolean isComplete(FieldPathUpdate update) { if (!(update instanceof AssignFieldPathUpdate)) { return false; } // Only consider field path updates that touch a top-level field as 'complete', // as these may be converted to regular field value updates. return ((update.getFieldPath().size() == 1) && update.getFieldPath().get(0).getType() == FieldPathEntry.Type.STRUCT_FIELD); }
private AssignFieldPathUpdate readAssignFieldPathUpdate(DocumentType documentType, String fieldPath, TokenBuffer buffer) { AssignFieldPathUpdate fieldPathUpdate = new AssignFieldPathUpdate(documentType, fieldPath); FieldValue fv = SingleValueReader.readSingleValue( buffer, fieldPathUpdate.getFieldPath().getResultingDataType()); fieldPathUpdate.setNewValue(fv); return fieldPathUpdate; }
@Override public FieldPath buildFieldPath(String remainFieldName) { if (remainFieldName.length() > 0 && remainFieldName.charAt(0) == '[') { int endPos = remainFieldName.indexOf(']'); if (endPos == -1) { throw new IllegalArgumentException("Array subscript must be closed with ]"); } else { FieldPath path = getNestedType().buildFieldPath(skipDotInString(remainFieldName, endPos)); List<FieldPathEntry> tmpPath = new ArrayList<FieldPathEntry>(path.getList()); if (remainFieldName.charAt(1) == '$') { tmpPath.add(0, FieldPathEntry.newVariableLookupEntry(remainFieldName.substring(2, endPos), getNestedType())); } else { tmpPath.add(0, FieldPathEntry.newArrayLookupEntry(Integer.parseInt(remainFieldName.substring(1, endPos)), getNestedType())); } return new FieldPath(tmpPath); } } return getNestedType().buildFieldPath(remainFieldName); }
@Override FieldPathIteratorHandler.ModificationStatus iterateNested(FieldPath fieldPath, int pos, FieldPathIteratorHandler handler) { if (pos < fieldPath.size()) { switch (fieldPath.get(pos).getType()) { case ARRAY_INDEX: final int elemIndex = fieldPath.get(pos).getLookupIndex(); return iterateSubset(elemIndex, elemIndex, fieldPath, null, pos + 1, handler); case VARIABLE: { FieldPathIteratorHandler.IndexValue val = handler.getVariables().get(fieldPath.get(pos).getVariableName()); if (val != null) { int idx = val.getIndex(); return iterateSubset(0, values.size() - 1, fieldPath, fieldPath.get(pos).getVariableName(), pos + 1, handler);
private AddFieldPathUpdate readAddFieldPathUpdate(DocumentType documentType, String fieldPath, TokenBuffer buffer) { AddFieldPathUpdate fieldPathUpdate = new AddFieldPathUpdate(documentType, fieldPath); FieldValue fv = SingleValueReader.readSingleValue( buffer, fieldPathUpdate.getFieldPath().getResultingDataType()); fieldPathUpdate.setNewValues((Array) fv); return fieldPathUpdate; }
@Override public FieldPathIteratorHandler.ModificationStatus iterateNested(FieldPath fieldPath, int pos, FieldPathIteratorHandler handler) { if (pos < fieldPath.size()) { if (fieldPath.get(pos).getType() == FieldPathEntry.Type.STRUCT_FIELD) { FieldValue fieldVal = getFieldValue(fieldPath.get(pos).getFieldRef()); if (fieldVal != null) { FieldPathIteratorHandler.ModificationStatus status = fieldVal.iterateNested(fieldPath, pos + 1, handler); if (status == FieldPathIteratorHandler.ModificationStatus.REMOVED) { removeFieldValue(fieldPath.get(pos).getFieldRef()); return FieldPathIteratorHandler.ModificationStatus.MODIFIED; } else { setFieldValue(fieldPath.get(pos).getFieldRef(), fieldVal); FieldValue newVal = fieldPath.get(pos).getFieldRef().getDataType().createFieldValue(); FieldPathIteratorHandler.ModificationStatus status = newVal.iterateNested(fieldPath, pos + 1, handler); if (status == FieldPathIteratorHandler.ModificationStatus.MODIFIED) { setFieldValue(fieldPath.get(pos).getFieldRef(), newVal); return status; throw new IllegalArgumentException("Illegal field path " + fieldPath.get(pos) + " for struct value"); } else { FieldPathIteratorHandler.ModificationStatus status = handler.modify(this);
public void read(AddFieldPathUpdate update) { DataType dt = update.getFieldPath().getResultingDataType(); FieldValue fv = dt.createFieldValue(); fv.deserialize(resolveField(update), this); update.setNewValues((Array)fv); }