/* Copyright (c) 2008 Google Inc.
*
* 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 com.google.gdata.model;
import com.google.gdata.util.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.SortedMap;
/**
* A mutable, thread-safe builder for the metadata for a particular attribute.
* This can be used to construct the default metadata for an attribute as well
* as add transforms on the attribute. The {@link #create} method can be used
* to create an immutable {@link AttributeMetadataRegistry} from this builder.
*
* <p>As all attributes share a common type {@link Attribute}, attributes are
* indexed only by their QName, so this registry stores all information for
* attributes that share a QName. To build a particular set of metadata, call
* {@link #build} with the desired parent, attribute, and context.
*
*
*/
final class AttributeMetadataRegistryBuilder {
// The root metadata registry.
private final MetadataRegistry root;
// A map of creators by transformKey for the attribute.
private final SortedMap<TransformKey, AttributeCreatorImpl> creators
= Maps.newTreeMap();
/**
* Creates new empty attribute metadata registry builder as part of the
* given root registry.
*/
AttributeMetadataRegistryBuilder(MetadataRegistry root) {
this.root = root;
}
/**
* Merges the values from an existing attribute registry builder.
*/
void merge(AttributeMetadataRegistryBuilder other) {
for (Map.Entry<TransformKey, AttributeCreatorImpl> entry
: other.creators.entrySet()) {
TransformKey key = entry.getKey();
AttributeCreatorImpl creator = creators.get(key);
if (creator == null) {
creator = new AttributeCreatorImpl(root, key);
creators.put(key, creator);
}
creator.merge(entry.getValue());
}
}
/**
* Create an immutable attribute metadata registry from this builder.
*/
AttributeMetadataRegistry create(Schema schema) {
return new AttributeMetadataRegistry(schema, this);
}
/**
* Creates the metadata for the attribute in the given parent and context.
* Parent and attribute must not be null, but a null context means metadata
* in the default context.
*/
AttributeCreatorImpl build(ElementKey<?, ?> parent,
AttributeKey<?> key, MetadataContext context) {
Preconditions.checkNotNull(parent, "parent");
Preconditions.checkNotNull(key, "key");
TransformKey transformKey = TransformKey.forTransform(parent, key, context);
synchronized (root) {
AttributeCreatorImpl creator = creators.get(transformKey);
if (creator == null) {
creator = new AttributeCreatorImpl(root, transformKey);
creators.put(transformKey, creator);
root.dirty();
}
return creator;
}
}
/**
* Returns an immutable copy of the creators in this builder.
*/
Map<TransformKey, AttributeCreatorImpl> getCreators() {
return ImmutableMap.copyOf(creators);
}
}