001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */ 
017    package org.apache.commons.betwixt.io.read;
018    
019    import org.apache.commons.betwixt.AttributeDescriptor;
020    import org.apache.commons.betwixt.ElementDescriptor;
021    import org.xml.sax.Attributes;
022    
023    /**
024     * Executes mapping action for a subgraph.
025     * It is intended that most MappingAction's will not need to maintain state.
026     * 
027     * @author <a href='http://commons.apache.org/'>Apache Commons Team</a>
028     * @version $Revision: 561314 $
029     */
030    public abstract class MappingAction {
031    
032           
033        public abstract MappingAction next(
034            String namespace,
035            String name,
036            Attributes attributes,
037            ReadContext context)
038            throws Exception;
039    
040        /**
041         * Executes mapping action on new element.
042         * @param namespace
043         * @param name
044         * @param attributes Attributes not null
045         * @param context Context not null
046         * @return the MappingAction to be used to map the sub-graph 
047         * under this element
048         * @throws Exception
049         */
050        public abstract MappingAction begin(
051            String namespace,
052            String name,
053            Attributes attributes,
054            ReadContext context)
055            throws Exception;
056    
057        /**
058         * Executes mapping action for element body text
059         * @param text
060         * @param context
061         * @throws Exception
062         */
063        public abstract void body(String text, ReadContext context)
064            throws Exception;
065    
066        /**
067         * Executes mapping action one element ends
068         * @param context
069         * @throws Exception
070         */
071        public abstract void end(ReadContext context) throws Exception;
072    
073        public static final MappingAction EMPTY = new MappingAction.Base();
074    
075        public static final MappingAction IGNORE = new MappingAction.Ignore();    
076        
077        private static final class Ignore extends MappingAction {
078    
079            public MappingAction next(String namespace, String name, Attributes attributes, ReadContext context) throws Exception {
080                return this;
081            }
082    
083            public MappingAction begin(String namespace, String name, Attributes attributes, ReadContext context) throws Exception {
084                return this;
085            }
086    
087            public void body(String text, ReadContext context) throws Exception {
088                // do nothing
089            }
090    
091            public void end(ReadContext context) throws Exception {
092                // do nothing
093            }
094            
095        }
096    
097        /**
098         * Basic action.
099         * 
100         * @author <a href='http://commons.apache.org/'>Apache Commons Team</a>
101         * @version $Revision: 561314 $
102         */
103        public static class Base extends MappingAction {
104            
105            public MappingAction next(
106                String namespace,
107                String name,
108                Attributes attributes,
109                ReadContext context)
110                throws Exception {       
111            
112                return context.getActionMappingStrategy().getMappingAction(namespace, name, attributes, context);
113            }
114            
115            /**
116             * @see org.apache.commons.betwixt.io.read.MappingAction#begin(String, String, Attributes, ReadContext)
117             */
118            public MappingAction begin(
119                String namespace,
120                String name,
121                Attributes attributes,
122                ReadContext context)
123                throws Exception {
124                // TODO: i'm not too sure about this part of the design
125                // i'm not sure whether base should give base behaviour or if it should give standard behaviour
126                // i'm hoping that things will become clearer once the descriptor logic has been cleared 
127                ElementDescriptor descriptor = context.getCurrentDescriptor();
128                if (descriptor != null) {
129    
130                    AttributeDescriptor[] attributeDescriptors =
131                        descriptor.getAttributeDescriptors();
132                    context.populateAttributes(attributeDescriptors, attributes);
133                }
134                return this;
135            }
136    
137            /**
138             * @see MappingAction#body(String, ReadContext)
139             */
140            public void body(String text, ReadContext context) throws Exception {
141                // do nothing
142            }
143    
144            /**
145             * @see MappingAction#end(ReadContext)
146             */
147            public void end(ReadContext context) throws Exception {
148                // do nothing
149                // TODO: this is a temporary refactoring
150                // it would be better to do this in the rule
151                // need to move more logic into the context and out of the rule
152                context.popElement();
153            }
154    
155        }
156    }