/*
* Copyright 2003, 2004 The Apache Software Foundation
*
* 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.apache.ws.jaxme.generator.sg.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.ws.jaxme.generator.Generator;
import org.apache.ws.jaxme.generator.impl.Inliner;
import org.apache.ws.jaxme.generator.sg.Context;
import org.apache.ws.jaxme.generator.sg.Facet;
import org.apache.ws.jaxme.generator.sg.GroupSG;
import org.apache.ws.jaxme.generator.sg.ObjectSG;
import org.apache.ws.jaxme.generator.sg.ObjectSGChain;
import org.apache.ws.jaxme.generator.sg.SGFactory;
import org.apache.ws.jaxme.generator.sg.SGFactoryChain;
import org.apache.ws.jaxme.generator.sg.SchemaSG;
import org.apache.ws.jaxme.generator.sg.SchemaSGChain;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.generator.sg.TypeSGChain;
import org.apache.ws.jaxme.logging.Logger;
import org.apache.ws.jaxme.logging.LoggerAccess;
import org.apache.ws.jaxme.xs.SchemaTransformer;
import org.apache.ws.jaxme.xs.XSAny;
import org.apache.ws.jaxme.xs.XSElement;
import org.apache.ws.jaxme.xs.XSEnumeration;
import org.apache.ws.jaxme.xs.XSGroup;
import org.apache.ws.jaxme.xs.XSObjectFactory;
import org.apache.ws.jaxme.xs.XSParser;
import org.apache.ws.jaxme.xs.XSSchema;
import org.apache.ws.jaxme.xs.XSType;
import org.apache.ws.jaxme.xs.jaxb.JAXBProperty;
import org.apache.ws.jaxme.xs.jaxb.impl.JAXBObjectFactoryImpl;
import org.apache.ws.jaxme.xs.jaxb.impl.JAXBParser;
import org.apache.ws.jaxme.xs.jaxb.impl.JAXBXsObjectFactoryImpl;
import org.apache.ws.jaxme.xs.parser.XSContext;
import org.apache.ws.jaxme.xs.xml.XsObjectFactory;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class JAXBSGFactory implements SGFactoryChain {
private final static Logger log = LoggerAccess.getLogger(JAXBSGFactory.class);
private final Generator generator;
private SchemaSG schemaSG;
private Map groups = new HashMap();
private Map objects = new HashMap();
private Map types = new HashMap();
private List groupsByOrder = new ArrayList();
private List objectsByOrder = new ArrayList();
private List typesByOrder = new ArrayList();
/** Creates a new instance for the given {@link Generator}.
*/
public JAXBSGFactory(Generator pGenerator) {
generator = pGenerator;
}
public void init(SGFactory pController) {
}
public Generator getGenerator(SGFactory pController) {
return generator;
}
public GroupSG getGroupSG(SGFactory pController, XSGroup pGroup) throws SAXException {
GroupSG result = (GroupSG) groups.get(pGroup);
if (result == null) {
result = pController.newGroupSG(pGroup);
groups.put(pGroup, result);
groupsByOrder.add(result);
result.init();
}
return result;
}
public GroupSG newGroupSG(SGFactory pController, XSGroup pGroup) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created");
}
return new GroupSGImpl(new JAXBGroupSG(pController, schemaSG, pGroup));
}
public GroupSG getGroupSG(SGFactory pController, XSGroup pGroup, Context pClassContext) throws SAXException {
GroupSG result = pController.newGroupSG(pGroup, pClassContext);
result.init();
groupsByOrder.add(result);
return result;
}
public GroupSG newGroupSG(SGFactory pController, XSGroup pGroup, Context pClassContext) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created");
}
return new GroupSGImpl(new JAXBGroupSG(pController, schemaSG, pGroup, pClassContext));
}
public Object newObjectSG(SGFactory pController, XSElement pElement) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created.");
}
return new JAXBObjectSG(pController, schemaSG, pElement);
}
public ObjectSG getObjectSG(SGFactory pController, XSElement pElement) throws SAXException {
ObjectSG result = (ObjectSG) objects.get(pElement);
if (result == null) {
ObjectSGChain chain = (ObjectSGChain) pController.newObjectSG(pElement);
result = new ObjectSGImpl(chain);
objects.put(pElement, result);
objectsByOrder.add(result);
result.init();
}
return result;
}
public Object newObjectSG(SGFactory pController, XSAny pAny) {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created.");
}
return new JAXBObjectSG(pController, schemaSG, pAny);
}
public ObjectSG getObjectSG(SGFactory pController, XSAny pAny, Context pContext) throws SAXException {
ObjectSGChain chain = (ObjectSGChain) pController.newObjectSG(pAny);
ObjectSG result = new ObjectSGImpl(chain);
result.init();
return result;
}
public Object newObjectSG(SGFactory pController, XSElement pElement, Context pContext) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created.");
}
return new JAXBObjectSG(pController, schemaSG, pElement, pContext);
}
public ObjectSG getObjectSG(SGFactory pController, XSElement pElement, Context pContext) throws SAXException {
ObjectSGChain chain = (ObjectSGChain) pController.newObjectSG(pElement, pContext);
ObjectSG result = new ObjectSGImpl(chain);
result.init();
return result;
}
public SchemaSG getSchemaSG(SGFactory pController, XSSchema pSchema) throws SAXException {
if (schemaSG == null) {
SchemaSGChain chain = (SchemaSGChain) pController.newSchemaSG(pSchema);
schemaSG = new SchemaSGImpl(chain);
schemaSG.init();
}
return schemaSG;
}
public SchemaSG getSchemaSG(SGFactory pController) {
if (schemaSG == null) {
throw new IllegalStateException("A factory has not yet been created.");
}
return schemaSG;
}
public Object newSchemaSG(SGFactory pController, XSSchema pSchema) throws SAXException {
return new JAXBSchemaSG(pController, pSchema);
}
public TypeSG getTypeSG(SGFactory pController, XSType pType, JAXBProperty.BaseType pBaseType) throws SAXException {
final String mName = "getTypeSG(XSType)";
TypeSG result = (TypeSG) types.get(pType);
if (result == null || pBaseType != null) {
log.finest(mName, "->", pType.getName());
TypeSGChain chain = (TypeSGChain) pController.newTypeSG(pType, pBaseType);
result = new TypeSGImpl(chain);
if (pBaseType == null) {
types.put(pType, result);
typesByOrder.add(result);
}
result.init();
log.finest(mName, "<-", new Object[]{chain, result});
}
return result;
}
public Object newTypeSG(SGFactory pController, XSType pType, JAXBProperty.BaseType pBaseType) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created");
}
return new JAXBTypeSG(pController, schemaSG, pType, pBaseType);
}
public TypeSG getTypeSG(SGFactory pController, XSType pType, Context pClassContext, XsQName pName, JAXBProperty.BaseType pBaseType) throws SAXException {
final String mName = "getTypeSG(XSType,ClassContext)";
log.finest(mName, "->", new Object[]{pType, pClassContext});
TypeSGChain chain = (TypeSGChain) pController.newTypeSG(pType, pClassContext, pName, pBaseType);
TypeSG result = new TypeSGImpl(chain);
typesByOrder.add(result);
result.init();
log.finest(mName, "<-", new Object[]{chain, result});
return result;
}
public Object newTypeSG(SGFactory pController, XSType pType, Context pClassContext, XsQName pName,
JAXBProperty.BaseType pBaseType) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created");
}
return new JAXBTypeSG(pController, schemaSG, pType, pClassContext, pName, pBaseType);
}
public Object newTypeSG(SGFactory pController, XSType pType, XsQName pName,
JAXBProperty.BaseType pBaseType) throws SAXException {
if (schemaSG == null) {
throw new IllegalStateException("A schema has not yet been created");
}
return new JAXBTypeSG(pController, schemaSG, pType, pName, pBaseType);
}
public TypeSG getTypeSG(SGFactory pController, XSType pType, XsQName pName, JAXBProperty.BaseType pBaseType) throws SAXException {
TypeSGChain chain = (TypeSGChain) pController.newTypeSG(pType, pName, pBaseType);
TypeSG result = new TypeSGImpl(chain);
typesByOrder.add(result);
result.init();
return result;
}
public XSParser newXSParser(SGFactory pController) throws SAXException {
XSParser parser = new JAXBParser();
XSContext context = parser.getContext();
context.setXsObjectFactory(pController.newXsObjectFactory());
context.setXSObjectFactory(pController.newXSObjectFactory());
return parser;
}
public Facet newFacet(SGFactory pController, XSType pType, XSEnumeration[] pEnumerations) throws SAXException {
return new FacetImpl(pType, pEnumerations);
}
public TypeSG[] getTypes(SGFactory pController) {
return (TypeSG[]) typesByOrder.toArray(new TypeSG[typesByOrder.size()]);
}
public GroupSG[] getGroups(SGFactory pController) {
return (GroupSG[]) groupsByOrder.toArray(new GroupSG[groupsByOrder.size()]);
}
public ObjectSG[] getObjects(SGFactory pController) {
return (ObjectSG[]) objectsByOrder.toArray(new ObjectSG[objectsByOrder.size()]);
}
public XsObjectFactory newXsObjectFactory(SGFactory pController) throws SAXException {
return new JAXBXsObjectFactoryImpl(){
public XMLReader newXMLReader(boolean pValidating) throws ParserConfigurationException, SAXException{
XMLReader xr = super.newXMLReader(pValidating);
EntityResolver entityResolver = generator.getEntityResolver();
if (entityResolver != null) {
xr.setEntityResolver(entityResolver);
}
return xr;
}
};
}
public XSObjectFactory newXSObjectFactory(SGFactory pController) throws SAXException {
return new JAXBObjectFactoryImpl(){
public SchemaTransformer getSchemaTransformer() {
Document[] bindings = generator.getBindings();
if (bindings == null || bindings.length == 0) {
return null;
} else {
return new Inliner(bindings);
}
}
};
}
}