001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.web.deployment;
019    
020    import javax.xml.namespace.QName;
021    
022    import org.apache.geronimo.common.DeploymentException;
023    import org.apache.geronimo.deployment.xbeans.ModuleDocument;
024    import org.apache.geronimo.schema.SchemaConversionUtils;
025    import org.apache.geronimo.xbeans.geronimo.security.GerSecurityDocument;
026    import org.apache.geronimo.xbeans.geronimo.web.GerWebAppDocument;
027    import org.apache.xmlbeans.XmlCursor;
028    import org.apache.xmlbeans.XmlObject;
029    
030    /**
031     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
032     */
033    public class GenericToSpecificPlanConverter {
034    
035        private static final QName GENERIC_QNAME = GerWebAppDocument.type.getDocumentElementName();
036        private static final String GENERIC_NAMESPACE = GENERIC_QNAME.getNamespaceURI();
037        private static final String OLD_GENERIC_NAMESPACE = "http://geronimo.apache.org/xml/ns/web";
038    
039        private static final QName GENERIC_CONFIG_QNAME = new QName(GENERIC_NAMESPACE, "container-config");
040        private static final QName OLD_GENERIC_CONFIG_QNAME = new QName(OLD_GENERIC_NAMESPACE, "container-config");
041        private static final String SYSTEM_NAMESPACE = ModuleDocument.type.getDocumentElementName().getNamespaceURI();
042        private static final QName SECURITY_QNAME = GerSecurityDocument.type.getDocumentElementName();
043        private final String configNamespace;
044        private final String namespace;
045        private final String element;
046    
047        public GenericToSpecificPlanConverter(String configNamespace, String namespace, String element) {
048            this.configNamespace = configNamespace;
049            this.namespace = namespace;
050            this.element = element;
051        }
052    
053        public XmlObject convertToSpecificPlan(XmlObject plan) throws DeploymentException {
054            XmlCursor rawCursor = plan.newCursor();
055            try {
056                if (SchemaConversionUtils.findNestedElement(rawCursor, "web-app")) {
057                    XmlCursor temp = rawCursor.newCursor();
058                    String namespace = temp.getName().getNamespaceURI();
059                    temp.dispose();
060                    if(!namespace.equals(GENERIC_NAMESPACE) && !namespace.equals(this.namespace) && !namespace.equals(OLD_GENERIC_NAMESPACE)) {
061                        throw new DeploymentException("Cannot handle web plan with namespace "+namespace+" -- expecting "+GENERIC_NAMESPACE+" or "+this.namespace);
062                    }
063    
064                    XmlObject webPlan = rawCursor.getObject().copy();
065    
066                    XmlCursor cursor = webPlan.newCursor();
067                    XmlCursor end = cursor.newCursor();
068                    try {
069                        cursor.push();
070                        if (cursor.toChild(GENERIC_CONFIG_QNAME) || cursor.toChild(OLD_GENERIC_CONFIG_QNAME)) {
071                            XmlCursor source = cursor.newCursor();
072                            cursor.push();
073                            cursor.toEndToken();
074                            cursor.toNextToken();
075                            try {
076                                if (source.toChild(configNamespace, element)) {
077                                    source.copyXmlContents(cursor);
078                                }
079    
080                            } finally {
081                                source.dispose();
082                            }
083                            cursor.pop();
084                            cursor.removeXml();
085                        }
086                        cursor.pop();
087                        cursor.push();
088                        while (cursor.hasNextToken()) {
089                            if (cursor.isStart()) {
090                                if (!SchemaConversionUtils.convertSingleElementToGeronimoSubSchemas(cursor, end)
091                                && !this.namespace.equals(cursor.getName().getNamespaceURI())) {
092                                    cursor.setName(new QName(this.namespace, cursor.getName().getLocalPart()));
093                                }
094                            }
095                            cursor.toNextToken();
096                        }
097                        //move security elements after refs
098    
099                        cursor.pop();
100                        cursor.push();
101                        if (cursor.toChild(this.namespace, "security-realm-name")) {
102                            XmlCursor other = cursor.newCursor();
103                            try {
104                                other.toParent();
105                                if (other.toChild(SYSTEM_NAMESPACE, "gbean")) {
106                                    other.toPrevToken();
107                                } else {
108                                    other.toEndToken();
109                                    other.toPrevToken();
110                                }
111                                cursor.moveXml(other);
112                                cursor.pop();
113                                cursor.push();
114                                if (cursor.toChild(SECURITY_QNAME)) {
115                                    cursor.moveXml(other);
116                                }
117                            } finally {
118                                other.dispose();
119                            }
120                        }
121                        cursor.pop();
122                        return webPlan;
123                    } finally {
124                        cursor.dispose();
125                        end.dispose();
126                    }
127                } else {
128                    throw new DeploymentException("No web-app element");
129                }
130            } finally {
131                rawCursor.dispose();
132            }
133        }
134    
135    }