Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.pshow.ecm.content.metadata; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.collections.CollectionUtils; import org.pshow.ecm.content.exception.SchemaRegistException; import org.pshow.ecm.content.model.definition.ConstraintDef; import org.pshow.ecm.content.model.definition.DataTypeDef; import org.pshow.ecm.content.model.definition.FacetDef; import org.pshow.ecm.content.model.definition.PSDef; import org.pshow.ecm.content.model.definition.NamespaceDef; import org.pshow.ecm.content.model.definition.PropertyDef; import org.pshow.ecm.content.model.definition.TypeDef; import org.pshow.ecm.persistence.dao.NamespaceDao; import org.pshow.ecm.persistence.entity.Namespace; import org.pshow.ecm.utils.cache.Store; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; /** * @author roy TODO: ??????? */ @Service("contentSchemaHolder") public class DefaultContetntSchemaHolder implements ContentSchemaHolder { private static final String ALL_NAMESPACE = "ps:all_namespace"; private static final String ALL_CONSTRAINT = "ps:all_constraint"; private static final String ALL_DATATYPE = "ps:all_datatype"; private static final String ALL_FACET = "ps:all_facet"; private static final String ALL_TYPE = "ps:all_type"; private Store<String, Object> store; private NamespaceDao namespaceDao; /* * (non-Javadoc) * * @see * org.pshow.repo.schema.ContentSchemaHolder#registContentSchemas(java.util * .List) */ @Override public void registContentSchemas(List<PSDef> schemas) { for (PSDef psModel : schemas) { registContentSchema(psModel); } } private void registConstraints(List<ConstraintDef> constraints) { if (CollectionUtils.isNotEmpty(constraints)) { for (ConstraintDef constraintModel : constraints) { checkConstraint(constraintModel); store.put(constraintModel.getName(), constraintModel); } putStoreSafe(ALL_CONSTRAINT, constraints); } } private void checkConstraint(ConstraintDef constraintModel) { if (hasConstraint(constraintModel.getName())) { throw new SchemaRegistException( String.format("Constraint regist error: duplicate constraint[%s]", constraintModel.getName())); } } private void registDataTypes(List<DataTypeDef> propertyTypes) { if (CollectionUtils.isNotEmpty(propertyTypes)) { for (DataTypeDef dataType : propertyTypes) { checkDataType(dataType); store.put(dataType.getName(), dataType); } putStoreSafe(ALL_DATATYPE, propertyTypes); } } /** * ???? * * @param dataType */ private void checkDataType(DataTypeDef dataType) { try { // ?? getClass().getClassLoader().loadClass(dataType.getJavaClassName()); } catch (ClassNotFoundException e) { throw new SchemaRegistException( String.format("DataType regist error: can't load class '%s' for datatype[%s]", dataType.getJavaClassName(), dataType.getName()), e); } // ? if (store.contains(dataType.getName())) { throw new SchemaRegistException( String.format("DataType regist error: duplicate datatype[%s]", dataType.getName())); } } private void registFacets(List<FacetDef> facets) { if (CollectionUtils.isNotEmpty(facets)) { for (FacetDef facet : facets) { checkFacet(facet); store.put(facet.getName(), facet); } putStoreSafe(ALL_FACET, facets); } } private void checkFacet(FacetDef facet) { if (hasFacet(facet.getName())) { throw new SchemaRegistException( String.format("ContentFacet regist error: duplicate content facet[%s]", facet.getName())); } List<PropertyDef> properties = facet.getProperties(); for (PropertyDef property : properties) { // ?? String datatype_name = property.getDataTypeName(); if (!hasRegisteredObject(datatype_name)) { throw new SchemaRegistException(String.format( "ContentFacet regist error: can't find datatype[%s] for property['%s'] of facet[%s]", datatype_name, property.getName(), facet.getName())); } // ??? List<String> constraintNames = property.getConstraints(); if (constraintNames != null) { for (String constraintName : constraintNames) { if (!hasConstraint(constraintName)) { throw new SchemaRegistException(String.format( "ContentFacet regist error: can't find constraint[%s] for property['%s'] of facet[%s]", constraintName, property.getName(), facet.getName())); } } } } } private void registTypes(List<TypeDef> types) { if (CollectionUtils.isNotEmpty(types)) { for (TypeDef type : types) { checkContentType(type); store.put(type.getName(), type); } putStoreSafe(ALL_TYPE, types); } } private <E> void putStoreSafe(String key, List<E> value) { if (store.contains(key)) { List<E> old_all = this.getRegisteredObject(key, new ArrayList<E>()); List<E> new_all = new ArrayList<E>(value.size() + old_all.size()); new_all.addAll(value); new_all.addAll(old_all); store.put(key, new_all); } else { store.put(key, value); } } private <K, V> void putStoreSafe(String key, Map<K, V> value) { if (store.contains(key)) { Map<K, V> old_all = this.getRegisteredObject(key, Maps.synchronizedBiMap(HashBiMap.<K, V>create())); Map<K, V> new_all = Maps.synchronizedBiMap(HashBiMap.<K, V>create(value.size() + old_all.size())); new_all.putAll(value); new_all.putAll(old_all); store.put(key, new_all); } else { store.put(key, value); } } private void checkContentType(TypeDef type) { if (hasContentType(type.getName())) { throw new SchemaRegistException( String.format("ContentType regist error: duplicate content type[%s]", type.getName())); } List<PropertyDef> properties = type.getProperties(); for (PropertyDef property : properties) { // ?? String datatype_name = property.getDataTypeName(); if (!hasRegisteredObject(datatype_name)) { throw new SchemaRegistException(String.format( "ContentType regist error: can't find datatype[%s] for property['%s'] of type[%s]", datatype_name, property.getName(), type.getName())); } // ??? List<String> constraintNames = property.getConstraints(); if (constraintNames != null) { for (String constraintName : constraintNames) { if (!hasConstraint(constraintName)) { throw new SchemaRegistException(String.format( "ContentType regist error: can't find constraint[%s] for property['%s'] of facet[%s]", constraintName, property.getName(), type.getName())); } } } } } private void registNamespaces(List<NamespaceDef> list) { // namespace List<NamespaceDef> exist_namespaces = loadNamespacesFromDB(); if (list != null) { for (NamespaceDef psNamespace : list) { if (!exist_namespaces.contains(psNamespace)) { // ?namespace???namespace namespaceDao.save(new Namespace(psNamespace.getUri(), psNamespace.getPrefix())); exist_namespaces.add(psNamespace); } } } BiMap<String, String> namespaces = Maps.synchronizedBiMap(HashBiMap.<String, String>create()); for (NamespaceDef psNamespace : exist_namespaces) { checkNamespace(namespaces, psNamespace); namespaces.put(psNamespace.getUri(), psNamespace.getPrefix()); } putStoreSafe(ALL_NAMESPACE, namespaces); } /** * ???namespace * * @param namespaces * @param psNamespace */ private void checkNamespace(BiMap<String, String> namespaces, NamespaceDef psNamespace) { // ???uri if (namespaces.containsKey(psNamespace.getUri())) { throw new SchemaRegistException( String.format("Namespace regist error: duplicate namespace uri -> %s", psNamespace.toString())); } // ???prefix if (namespaces.containsValue(psNamespace.getPrefix())) { throw new SchemaRegistException(String .format("Namespace regist error: duplicate namespace prefix -> %s", psNamespace.toString())); } } private List<NamespaceDef> loadNamespacesFromDB() { ArrayList<NamespaceDef> namespaces = new ArrayList<NamespaceDef>(); namespaces.addAll(convertNamespace(namespaceDao.findAll())); return namespaces; } private Collection<? extends NamespaceDef> convertNamespace(Iterable<Namespace> findAllNamespaces) { ArrayList<NamespaceDef> result = new ArrayList<NamespaceDef>(); for (Namespace namespaceModel : findAllNamespaces) { result.add(new NamespaceDef(namespaceModel.getUri(), namespaceModel.getPrefix())); } return result; } /* * (non-Javadoc) * * @see * org.pshow.repo.schema.ContentSchemaHolder#registContentSchema(org.pshow * .repo.datamodel.content.definition.PSModel) */ @Override public void registContentSchema(PSDef schema) { registNamespaces(schema.getNamespaces()); registDataTypes(schema.getPropertyTypes()); registConstraints(schema.getConstraints()); registTypes(schema.getTypes()); registFacets(schema.getFacets()); } /* * (non-Javadoc) * * @see * org.pshow.repo.schema.ContentSchemaHolder#getNamespace(org.pshow.repo * .datamodel.namespace.String) */ @Override public NamespaceDef getNamespaceByUri(String uri) { BiMap<String, String> namespaces = getRegisteredObject(ALL_NAMESPACE, HashBiMap.<String, String>create()); String prefix = namespaces.get(uri); if (prefix != null) { return new NamespaceDef(uri, prefix); } return null; } /* * (non-Javadoc) * * @see org.pshow.repo.schema.ContentSchemaHolder#getAllNamespace() */ @Override public List<NamespaceDef> getAllNamespace() { ArrayList<NamespaceDef> namespace = new ArrayList<NamespaceDef>(); BiMap<String, String> namespaces = getRegisteredObject(ALL_NAMESPACE, HashBiMap.<String, String>create()); Iterator<Entry<String, String>> iterator = namespaces.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, String> entry = (Entry<String, String>) iterator.next(); namespace.add(new NamespaceDef(entry.getKey(), entry.getValue())); } return namespace; } /* * (non-Javadoc) * * @see * org.pshow.repo.schema.ContentSchemaHolder#getContentType(org.pshow.repo * .datamodel.namespace.String) */ @Override public TypeDef getContentType(String name) { return getRegisteredObject(name, new TypeDef()); } /* * (non-Javadoc) * * @see org.pshow.repo.schema.ContentSchemaHolder#getAllContentType() */ @Override public List<TypeDef> getAllContentType() { return getRegisteredObject(ALL_TYPE, new ArrayList<TypeDef>()); } @Override public boolean hasRegisteredObject(String name) { return store.contains(name); } @Override @SuppressWarnings("unchecked") public <E> E getRegisteredObject(String name, E e) { return (E) store.get(name); } @Override public FacetDef getFacet(String name) { return getRegisteredObject(name, new FacetDef()); } @Override public List<FacetDef> getAllFacet() { return getRegisteredObject(ALL_FACET, new ArrayList<FacetDef>()); } @Override public ConstraintDef getConstraint(String name) { return getRegisteredObject(name, new ConstraintDef()); } @Override public List<ConstraintDef> getAllConstraint() { return getRegisteredObject(ALL_CONSTRAINT, new ArrayList<ConstraintDef>()); } @Override public boolean hasNamespace(String name) { if (store.contains(name)) { return ((store.get(name) instanceof NamespaceDef) ? true : false); } return false; } @Override public boolean hasContentType(String name) { if (store.contains(name)) { return ((store.get(name) instanceof TypeDef) ? true : false); } return false; } @Override public boolean hasFacet(String name) { if (store.contains(name)) { return ((store.get(name) instanceof FacetDef) ? true : false); } return false; } @Override public boolean hasConstraint(String name) { if (store.contains(name)) { return ((store.get(name) instanceof ConstraintDef) ? true : false); } return false; } @Override public NamespaceDef getNamespaceByPrefix(String prefix) { BiMap<String, String> namespaces = getRegisteredObject(ALL_NAMESPACE, HashBiMap.<String, String>create()); String uri = namespaces.inverse().get(prefix); if (uri != null) { return new NamespaceDef(uri, prefix); } return null; } @Autowired @Qualifier("memoryStore") public void setStore(Store<String, Object> store) { this.store = store; } @Autowired public void setNamespaceDao(NamespaceDao namespaceDao) { this.namespaceDao = namespaceDao; } }