/*
* Copyright 2011 Outerthought bvba
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lilyproject.repository.impl;
import org.lilyproject.repository.api.FieldType;
import org.lilyproject.repository.api.QName;
import org.lilyproject.repository.api.RecordType;
import org.lilyproject.repository.api.RecordTypeBuilder;
import org.lilyproject.repository.api.RepositoryException;
import org.lilyproject.repository.api.SchemaId;
import org.lilyproject.repository.api.Scope;
import org.lilyproject.repository.api.TypeException;
import org.lilyproject.repository.api.TypeManager;
import org.lilyproject.repository.api.ValueType;
public class RecordTypeBuilderImpl implements RecordTypeBuilder {
private final TypeManager typeManager;
private RecordType recordType;
private String defaultNamespace;
private Scope defaultScope = Scope.NON_VERSIONED;
public RecordTypeBuilderImpl(TypeManager typeManager) throws TypeException {
this.typeManager = typeManager;
recordType = typeManager.newRecordType(null);
}
@Override
public RecordTypeBuilder defaultNamespace(String namespace) {
this.defaultNamespace = namespace;
return this;
}
@Override
public RecordTypeBuilder defaultScope(Scope scope) {
this.defaultScope = scope;
return this;
}
@Override
public RecordTypeBuilder name(String name) {
recordType.setName(resolveNamespace(name));
return this;
}
@Override
public RecordTypeBuilder name(String namespace, String name) {
recordType.setName(new QName(namespace, name));
return this;
}
@Override
public RecordTypeBuilder name(QName name) {
recordType.setName(name);
return this;
}
@Override
public RecordTypeBuilder id(SchemaId id) {
recordType.setId(id);
return this;
}
@Override
public RecordTypeBuilder field(SchemaId id, boolean mandatory) {
recordType.addFieldTypeEntry(id, mandatory);
return this;
}
@Override
public SupertypeBuilder supertype() {
return new SupertypeBuilderImpl();
}
@Override
@Deprecated
public MixinBuilder mixin() {
return new MixinBuilderImpl();
}
@Override
public RecordTypeBuilder reset() throws TypeException {
recordType = typeManager.newRecordType(null);
return this;
}
@Override
public RecordType build() {
return recordType;
}
@Override
public RecordType create() throws RepositoryException, InterruptedException {
return typeManager.createRecordType(recordType);
}
@Override
public RecordType createOrUpdate() throws RepositoryException, InterruptedException {
return typeManager.createOrUpdateRecordType(recordType);
}
@Override
public RecordType createOrUpdate(boolean refreshSubtypes) throws RepositoryException, InterruptedException {
return typeManager.createOrUpdateRecordType(recordType, refreshSubtypes);
}
@Override
public RecordType update() throws RepositoryException, InterruptedException {
return typeManager.updateRecordType(recordType);
}
@Override
public RecordType update(boolean refreshSubtypes) throws RepositoryException, InterruptedException {
return typeManager.updateRecordType(recordType, refreshSubtypes);
}
@Override
public FieldEntryBuilder fieldEntry() {
return new FieldEntryBuilderImpl();
}
private QName resolveNamespace(String name) {
if (defaultNamespace != null) {
return new QName(defaultNamespace, name);
}
QName recordTypeName = recordType.getName();
if (recordTypeName != null) {
return new QName(recordTypeName.getNamespace(), name);
}
throw new IllegalStateException("Namespace could not be resolved for name '" + name +
"' since no default namespace was given and no record type name is set.");
}
public class FieldEntryBuilderImpl implements FieldEntryBuilder {
private SchemaId id;
private boolean mandatory;
@Override
public FieldEntryBuilder id(SchemaId id) {
this.id = id;
return this;
}
@Override
public FieldEntryBuilder name(String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getFieldTypeByName(resolveNamespace(name)).getId();
return this;
}
@Override
public FieldEntryBuilder name(String namespace, String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getFieldTypeByName(new QName(namespace, name)).getId();
return this;
}
@Override
public FieldEntryBuilder name(QName name) throws RepositoryException, InterruptedException {
this.id = typeManager.getFieldTypeByName(name).getId();
return this;
}
@Override
public FieldEntryBuilder use(FieldType fieldType) {
this.id = fieldType.getId();
return this;
}
@Override
public FieldEntryBuilder mandatory() {
mandatory = true;
return this;
}
@Override
public FieldTypeBuilder defineField() {
return new FieldTypeBuilderImpl();
}
@Override
public RecordTypeBuilder add() {
recordType.addFieldTypeEntry(id, mandatory);
return RecordTypeBuilderImpl.this;
}
public class FieldTypeBuilderImpl implements RecordTypeBuilder.FieldTypeBuilder {
private QName name;
private ValueType valueType;
private Scope scope;
@Override
public FieldTypeBuilder name(String name) {
this.name = resolveNamespace(name);
return this;
}
@Override
public FieldTypeBuilder name(String namespace, String name) {
this.name = new QName(namespace, name);
return this;
}
@Override
public FieldTypeBuilder name(QName name) {
this.name = name;
return this;
}
@Override
public FieldTypeBuilder type(String valueType) throws RepositoryException, InterruptedException {
this.valueType = typeManager.getValueType(valueType);
return this;
}
@Override
public FieldTypeBuilder type(ValueType valueType) throws RepositoryException, InterruptedException {
this.valueType = valueType;
return this;
}
@Override
public FieldTypeBuilder scope(Scope scope) {
this.scope = scope;
return this;
}
private FieldType buildFieldType() throws RepositoryException, InterruptedException {
if (name == null) {
throw new IllegalStateException("Cannot create field type: name not set.");
}
// Apply defaults
if (valueType == null) {
valueType = typeManager.getValueType("STRING");
}
if (scope == null) {
scope = defaultScope;
}
return typeManager.newFieldType(valueType, name, scope);
}
@Override
public FieldEntryBuilder create() throws RepositoryException, InterruptedException {
FieldType fieldType = typeManager.createFieldType(buildFieldType());
FieldEntryBuilderImpl.this.id = fieldType.getId();
return FieldEntryBuilderImpl.this;
}
@Override
public FieldEntryBuilder createOrUpdate() throws RepositoryException, InterruptedException {
FieldType fieldType = typeManager.createOrUpdateFieldType(buildFieldType());
FieldEntryBuilderImpl.this.id = fieldType.getId();
return FieldEntryBuilderImpl.this;
}
}
}
public class SupertypeBuilderImpl implements SupertypeBuilder {
private SchemaId id;
private Long version;
@Override
public SupertypeBuilder id(SchemaId id) {
this.id = id;
return this;
}
@Override
public SupertypeBuilder name(String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(resolveNamespace(name), null).getId();
return this;
}
@Override
public SupertypeBuilder name(String namespace, String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(new QName(namespace, name), null).getId();
return this;
}
@Override
public SupertypeBuilder name(QName name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(name, null).getId();
return this;
}
@Override
public SupertypeBuilder version(long version) {
this.version = version;
return this;
}
@Override
public SupertypeBuilder use(RecordType recordType) {
this.id = recordType.getId();
this.version = recordType.getVersion();
return this;
}
@Override
public RecordTypeBuilder add() {
if (id == null) {
throw new IllegalStateException("Cannot add supertype: record type not set.");
}
recordType.addSupertype(id, version);
return RecordTypeBuilderImpl.this;
}
}
@Deprecated
public class MixinBuilderImpl implements MixinBuilder {
private SchemaId id;
private Long version;
@Override
@Deprecated
public MixinBuilder id(SchemaId id) {
this.id = id;
return this;
}
@Override
@Deprecated
public MixinBuilder name(String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(resolveNamespace(name), null).getId();
return this;
}
@Override
@Deprecated
public MixinBuilder name(String namespace, String name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(new QName(namespace, name), null).getId();
return this;
}
@Override
@Deprecated
public MixinBuilder name(QName name) throws RepositoryException, InterruptedException {
this.id = typeManager.getRecordTypeByName(name, null).getId();
return this;
}
@Override
@Deprecated
public MixinBuilder version(long version) {
this.version = version;
return this;
}
@Override
@Deprecated
public MixinBuilder use(RecordType recordType) {
this.id = recordType.getId();
this.version = recordType.getVersion();
return this;
}
@Override
@Deprecated
public RecordTypeBuilder add() {
if (id == null) {
throw new IllegalStateException("Cannot add mixin: record type not set.");
}
recordType.addMixin(id, version);
return RecordTypeBuilderImpl.this;
}
}
}