use of org.structr.core.entity.SchemaView in project structr by structr.
the class StructrSchema method replaceDatabaseSchema.
/**
* Replaces the current Structr schema with the given new schema. This
* method is the reverse of createFromDatabase above.
*
* @param app
* @param newSchema the new schema to replace the current Structr schema
*
* @throws FrameworkException
* @throws URISyntaxException
*/
public static void replaceDatabaseSchema(final App app, final JsonSchema newSchema) throws FrameworkException, URISyntaxException {
Services.getInstance().setOverridingSchemaTypesAllowed(true);
try (final Tx tx = app.tx()) {
for (final SchemaRelationshipNode schemaRelationship : app.nodeQuery(SchemaRelationshipNode.class).getAsList()) {
app.delete(schemaRelationship);
}
for (final SchemaNode schemaNode : app.nodeQuery(SchemaNode.class).getAsList()) {
app.delete(schemaNode);
}
for (final SchemaMethod schemaMethod : app.nodeQuery(SchemaMethod.class).getAsList()) {
app.delete(schemaMethod);
}
for (final SchemaMethodParameter schemaMethodParameter : app.nodeQuery(SchemaMethodParameter.class).getAsList()) {
app.delete(schemaMethodParameter);
}
for (final SchemaProperty schemaProperty : app.nodeQuery(SchemaProperty.class).getAsList()) {
app.delete(schemaProperty);
}
for (final SchemaView schemaView : app.nodeQuery(SchemaView.class).getAsList()) {
app.delete(schemaView);
}
newSchema.createDatabaseSchema(app, JsonSchema.ImportMode.replace);
tx.success();
}
}
use of org.structr.core.entity.SchemaView in project structr by structr.
the class StructrTypeDefinition method createDatabaseSchema.
AbstractSchemaNode createDatabaseSchema(final App app) throws FrameworkException {
final Map<String, SchemaProperty> schemaProperties = new TreeMap<>();
final Map<String, SchemaMethod> schemaMethods = new TreeMap<>();
final PropertyMap createProperties = new PropertyMap();
final PropertyMap nodeProperties = new PropertyMap();
// properties that always need to be set
createProperties.put(SchemaNode.isInterface, isInterface);
createProperties.put(SchemaNode.isAbstract, isAbstract);
createProperties.put(SchemaNode.category, category);
createProperties.put(SchemaNode.isBuiltinType, SchemaService.DynamicSchemaRootURI.equals(root.getId()));
final T schemaNode = createSchemaNode(app, createProperties);
for (final StructrPropertyDefinition property : properties) {
final SchemaProperty schemaProperty = property.createDatabaseSchema(app, schemaNode);
if (schemaProperty != null) {
schemaProperties.put(schemaProperty.getName(), schemaProperty);
}
}
// create views and associate the properties
for (final Entry<String, Set<String>> view : views.entrySet()) {
final List<SchemaProperty> viewProperties = new LinkedList<>();
final List<String> nonGraphProperties = new LinkedList<>();
for (final String propertyName : view.getValue()) {
final SchemaProperty property = schemaProperties.get(propertyName);
if (property != null) {
viewProperties.add(property);
} else {
nonGraphProperties.add(propertyName);
}
}
SchemaView viewNode = app.nodeQuery(SchemaView.class).and(SchemaView.schemaNode, schemaNode).and(SchemaView.name, view.getKey()).getFirst();
if (viewNode == null) {
viewNode = app.create(SchemaView.class, new NodeAttribute<>(SchemaView.schemaNode, schemaNode), new NodeAttribute<>(SchemaView.name, view.getKey()));
}
final PropertyMap updateProperties = new PropertyMap();
updateProperties.put(SchemaView.schemaProperties, viewProperties);
updateProperties.put(SchemaView.nonGraphProperties, StringUtils.join(nonGraphProperties, ", "));
// update properties of existing or new schema view node
viewNode.setProperties(SecurityContext.getSuperUserInstance(), updateProperties);
}
for (final StructrMethodDefinition method : methods) {
final SchemaMethod schemaMethod = method.createDatabaseSchema(app, schemaNode);
if (schemaMethod != null) {
schemaMethods.put(schemaMethod.getName(), schemaMethod);
}
}
// extends
if (baseTypeReference != null) {
final Object def = root.resolveURI(baseTypeReference);
if (def != null && def instanceof JsonType) {
final JsonType jsonType = (JsonType) def;
final String superclassName = "org.structr.dynamic." + jsonType.getName();
nodeProperties.put(SchemaNode.extendsClass, superclassName);
} else {
final Class superclass = StructrApp.resolveSchemaId(baseTypeReference);
if (superclass != null) {
if (superclass.isInterface()) {
nodeProperties.put(SchemaNode.implementsInterfaces, superclass.getName());
} else {
nodeProperties.put(SchemaNode.extendsClass, superclass.getName());
}
} else if ("https://structr.org/v1.1/definitions/FileBase".equals(baseTypeReference.toString())) {
// FileBase doesn't exist any more, but we need to support it for some time..
nodeProperties.put(SchemaNode.implementsInterfaces, "org.structr.web.entity.File");
} else if (!StructrApp.getSchemaBaseURI().relativize(baseTypeReference).isAbsolute()) {
// resolve internal type referenced in special URI
final URI base = StructrApp.getSchemaBaseURI().resolve("definitions/");
final URI type = base.relativize(baseTypeReference);
final String typeName = type.getPath();
final String parameters = type.getQuery();
final Class internal = StructrApp.getConfiguration().getNodeEntityClass(typeName);
if (internal != null) {
nodeProperties.put(SchemaNode.extendsClass, getParameterizedType(internal, parameters));
}
}
}
}
// implements
if (!implementedInterfaces.isEmpty()) {
final Set<String> interfaces = new LinkedHashSet<>();
for (final URI implementedInterface : implementedInterfaces) {
final Object def = root.resolveURI(implementedInterface);
if (def != null && def instanceof JsonType) {
final JsonType jsonType = (JsonType) def;
final String superclassName = "org.structr.dynamic." + jsonType.getName();
if (jsonType.isInterface()) {
interfaces.add(superclassName);
} else {
nodeProperties.put(SchemaNode.extendsClass, superclassName);
}
} else {
final Class superclass = StructrApp.resolveSchemaId(implementedInterface);
if (superclass != null) {
interfaces.add(superclass.getName());
} else {
logger.warn("Unable to resolve built-in type {} against Structr schema", implementedInterface);
StructrApp.resolveSchemaId(implementedInterface);
}
}
}
nodeProperties.put(SchemaNode.implementsInterfaces, StringUtils.join(interfaces, ", "));
}
schemaNode.setProperties(SecurityContext.getSuperUserInstance(), nodeProperties);
return schemaNode;
}
use of org.structr.core.entity.SchemaView in project structr by structr.
the class StructrTypeDefinition method deserialize.
void deserialize(final T schemaNode) {
for (final SchemaProperty property : schemaNode.getProperty(AbstractSchemaNode.schemaProperties)) {
final StructrPropertyDefinition propertyDefinition = StructrPropertyDefinition.deserialize(this, property);
if (propertyDefinition != null) {
properties.add(propertyDefinition);
}
}
for (final SchemaView view : schemaNode.getProperty(AbstractSchemaNode.schemaViews)) {
if (!View.INTERNAL_GRAPH_VIEW.equals(view.getName())) {
final Set<String> propertySet = new TreeSet<>();
for (final SchemaProperty property : view.getProperty(SchemaView.schemaProperties)) {
propertySet.add(property.getName());
}
final String nonGraphProperties = view.getProperty(SchemaView.nonGraphProperties);
if (nonGraphProperties != null) {
for (final String property : nonGraphProperties.split("[, ]+")) {
final String trimmed = property.trim();
if (StringUtils.isNotBlank(trimmed)) {
propertySet.add(trimmed);
}
}
}
if (!propertySet.isEmpty()) {
views.put(view.getName(), propertySet);
}
}
}
for (final SchemaMethod method : schemaNode.getProperty(AbstractSchemaNode.schemaMethods)) {
final StructrMethodDefinition newMethod = StructrMethodDefinition.deserialize(this, method);
if (newMethod != null) {
methods.add(newMethod);
}
}
// $extends
final String extendsClass = schemaNode.getProperty(SchemaNode.extendsClass);
if (extendsClass != null) {
final String typeName = resolveParameterizedType(extendsClass);
if (extendsClass.startsWith("org.structr.dynamic.")) {
this.baseTypeReference = root.getId().resolve("definitions/" + typeName);
} else {
this.baseTypeReference = StructrApp.getSchemaBaseURI().resolve("definitions/" + typeName);
}
}
// $implements
final String implementsInterfaces = schemaNode.getProperty(SchemaNode.implementsInterfaces);
if (implementsInterfaces != null) {
for (final String impl : implementsInterfaces.split("[, ]+")) {
final String trimmed = impl.trim();
if (StringUtils.isNotEmpty(trimmed)) {
final String typeName = trimmed.substring(trimmed.lastIndexOf(".") + 1);
if (trimmed.startsWith("org.structr.dynamic.")) {
this.implementedInterfaces.add(root.getId().resolve("definitions/" + typeName));
} else {
this.implementedInterfaces.add(StructrApp.getSchemaBaseURI().resolve("definitions/" + typeName));
}
}
}
}
this.isInterface = schemaNode.getProperty(SchemaNode.isInterface);
this.isAbstract = schemaNode.getProperty(SchemaNode.isAbstract);
this.category = schemaNode.getProperty(SchemaNode.category);
}
use of org.structr.core.entity.SchemaView in project structr by structr.
the class AdvancedSchemaTest method test04SchemaPropertyOrderInBuiltInViews.
@Test
public void test04SchemaPropertyOrderInBuiltInViews() {
try (final Tx tx = app.tx()) {
createAdminUser();
createResourceAccess("_schema", UiAuthenticator.AUTH_USER_GET);
tx.success();
} catch (Exception ex) {
logger.error("", ex);
}
final GenericProperty jsonName = new GenericProperty("jsonName");
SchemaNode test = null;
String id = null;
try (final Tx tx = app.tx()) {
// create test type
test = app.create(SchemaNode.class, "Test");
tx.success();
} catch (FrameworkException fex) {
fex.printStackTrace();
}
try (final Tx tx = app.tx()) {
// create view with sort order
final List<SchemaView> list = test.getProperty(SchemaNode.schemaViews);
// create properties
app.create(SchemaProperty.class, new NodeAttribute<>(SchemaProperty.schemaNode, test), new NodeAttribute<>(SchemaProperty.schemaViews, list), new NodeAttribute<>(SchemaProperty.propertyType, "String"), new NodeAttribute<>(SchemaProperty.name, "one"));
app.create(SchemaProperty.class, new NodeAttribute<>(SchemaProperty.schemaNode, test), new NodeAttribute<>(SchemaProperty.schemaViews, list), new NodeAttribute<>(SchemaProperty.propertyType, "String"), new NodeAttribute<>(SchemaProperty.name, "two"));
app.create(SchemaProperty.class, new NodeAttribute<>(SchemaProperty.schemaNode, test), new NodeAttribute<>(SchemaProperty.schemaViews, list), new NodeAttribute<>(SchemaProperty.propertyType, "String"), new NodeAttribute<>(SchemaProperty.name, "three"));
app.create(SchemaProperty.class, new NodeAttribute<>(SchemaProperty.schemaNode, test), new NodeAttribute<>(SchemaProperty.schemaViews, list), new NodeAttribute<>(SchemaProperty.propertyType, "String"), new NodeAttribute<>(SchemaProperty.name, "four"));
tx.success();
} catch (FrameworkException fex) {
fex.printStackTrace();
}
final Class type = StructrApp.getConfiguration().getNodeEntityClass("Test");
final List<PropertyKey> list = new LinkedList<>(StructrApp.getConfiguration().getPropertySet(type, "public"));
Assert.assertEquals("Invalid number of properties in sorted view", 6, list.size());
Assert.assertEquals("id", list.get(0).dbName());
Assert.assertEquals("type", list.get(1).dbName());
Assert.assertEquals("one", list.get(2).dbName());
Assert.assertEquals("two", list.get(3).dbName());
Assert.assertEquals("three", list.get(4).dbName());
Assert.assertEquals("four", list.get(5).dbName());
try (final Tx tx = app.tx()) {
for (final SchemaView testView : test.getProperty(SchemaNode.schemaViews)) {
// modify sort order
testView.setProperty(SchemaView.sortOrder, "type, one, id, two, three, four, name");
}
// create test entity
final NodeInterface node = app.create(StructrApp.getConfiguration().getNodeEntityClass("Test"));
// save UUID for later
id = node.getUuid();
tx.success();
} catch (FrameworkException fex) {
fex.printStackTrace();
}
final List<PropertyKey> list2 = new LinkedList<>(StructrApp.getConfiguration().getPropertySet(type, "public"));
Assert.assertEquals("Invalid number of properties in sorted view", 6, list2.size());
Assert.assertEquals("id", list2.get(0).dbName());
Assert.assertEquals("type", list2.get(1).dbName());
Assert.assertEquals("one", list2.get(2).dbName());
Assert.assertEquals("two", list2.get(3).dbName());
Assert.assertEquals("three", list2.get(4).dbName());
Assert.assertEquals("four", list2.get(5).dbName());
// test schema resource
RestAssured.given().contentType("application/json; charset=UTF-8").filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(201)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(400)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(404)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(422)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(500)).headers("X-User", ADMIN_USERNAME, "X-Password", ADMIN_PASSWORD).expect().statusCode(200).body("result", hasSize(6)).body("result[0].jsonName", equalTo("id")).body("result[1].jsonName", equalTo("type")).body("result[2].jsonName", equalTo("one")).body("result[3].jsonName", equalTo("two")).body("result[4].jsonName", equalTo("three")).body("result[5].jsonName", equalTo("four")).when().get("/_schema/Test/public");
// test actual REST resource (not easy to extract and verify
// JSON property order, that's why we're using replaceAll and
// string comparison..
final String[] actual = RestAssured.given().contentType("application/json; charset=UTF-8").filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(200)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(201)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(400)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(404)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(422)).filter(ResponseLoggingFilter.logResponseIfStatusCodeIs(500)).headers("X-User", ADMIN_USERNAME, "X-Password", ADMIN_PASSWORD).expect().statusCode(200).when().get("/Test").body().asString().replaceAll("[\\s]+", "").split("[\\W]+");
// we can only test the actual ORDER of the JSON result object by splitting it on whitespace and validating the resulting array
assertEquals("Invalid JSON result for sorted property view", "", actual[0]);
assertEquals("Invalid JSON result for sorted property view", "query_time", actual[1]);
assertEquals("Invalid JSON result for sorted property view", "0", actual[2]);
assertEquals("Invalid JSON result for sorted property view", "result_count", actual[4]);
assertEquals("Invalid JSON result for sorted property view", "1", actual[5]);
assertEquals("Invalid JSON result for sorted property view", "result", actual[6]);
assertEquals("Invalid JSON result for sorted property view", "id", actual[7]);
assertEquals("Invalid JSON result for sorted property view", id, actual[8]);
assertEquals("Invalid JSON result for sorted property view", "type", actual[9]);
assertEquals("Invalid JSON result for sorted property view", "Test", actual[10]);
assertEquals("Invalid JSON result for sorted property view", "one", actual[11]);
assertEquals("Invalid JSON result for sorted property view", "null", actual[12]);
assertEquals("Invalid JSON result for sorted property view", "two", actual[13]);
assertEquals("Invalid JSON result for sorted property view", "null", actual[14]);
assertEquals("Invalid JSON result for sorted property view", "three", actual[15]);
assertEquals("Invalid JSON result for sorted property view", "null", actual[16]);
assertEquals("Invalid JSON result for sorted property view", "four", actual[17]);
assertEquals("Invalid JSON result for sorted property view", "null", actual[18]);
assertEquals("Invalid JSON result for sorted property view", "serialization_time", actual[19]);
// try built-in function
try {
final List<GraphObjectMap> list3 = (List) new TypeInfoFunction().apply(new ActionContext(securityContext), null, new Object[] { "Test", "public" });
Assert.assertEquals("Invalid number of properties in sorted view", 6, list3.size());
Assert.assertEquals("id", list3.get(0).get(jsonName));
Assert.assertEquals("type", list3.get(1).get(jsonName));
Assert.assertEquals("one", list3.get(2).get(jsonName));
Assert.assertEquals("two", list3.get(3).get(jsonName));
Assert.assertEquals("three", list3.get(4).get(jsonName));
Assert.assertEquals("four", list3.get(5).get(jsonName));
} catch (FrameworkException fex) {
fex.printStackTrace();
}
// try scripting call
try {
final List<GraphObjectMap> list4 = (List) Scripting.evaluate(new ActionContext(securityContext), null, "${type_info('Test', 'public')}", "test");
Assert.assertEquals("Invalid number of properties in sorted view", 6, list4.size());
Assert.assertEquals("id", list4.get(0).get(jsonName));
Assert.assertEquals("type", list4.get(1).get(jsonName));
Assert.assertEquals("one", list4.get(2).get(jsonName));
Assert.assertEquals("two", list4.get(3).get(jsonName));
Assert.assertEquals("three", list4.get(4).get(jsonName));
Assert.assertEquals("four", list4.get(5).get(jsonName));
} catch (FrameworkException fex) {
fex.printStackTrace();
}
}
Aggregations