1   /*
2    * Copyright 2003 - 2013 The eFaps Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.update;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.net.URL;
26  import java.net.URLConnection;
27  import java.util.HashMap;
28  import java.util.Map;
29  import java.util.Stack;
30  
31  import org.efaps.update.schema.access.AccessSetUpdate;
32  import org.efaps.update.schema.access.AccessTypeUpdate;
33  import org.efaps.update.schema.common.MsgPhraseUpdate;
34  import org.efaps.update.schema.common.NumberGeneratorUpdate;
35  import org.efaps.update.schema.common.SystemConfigurationUpdate;
36  import org.efaps.update.schema.datamodel.DimensionUpdate;
37  import org.efaps.update.schema.datamodel.SQLTableUpdate;
38  import org.efaps.update.schema.datamodel.StatusGroupUpdate;
39  import org.efaps.update.schema.datamodel.TypeUpdate;
40  import org.efaps.update.schema.db.StoreUpdate;
41  import org.efaps.update.schema.dbproperty.DBPropertiesUpdate;
42  import org.efaps.update.schema.help.HelpMenuUpdate;
43  import org.efaps.update.schema.integration.WebDAVUpdate;
44  import org.efaps.update.schema.program.BPMImageUpdate;
45  import org.efaps.update.schema.program.JasperImageUpdate;
46  import org.efaps.update.schema.program.JasperReportUpdate;
47  import org.efaps.update.schema.program.WikiImageUpdate;
48  import org.efaps.update.schema.ui.CommandUpdate;
49  import org.efaps.update.schema.ui.FormUpdate;
50  import org.efaps.update.schema.ui.ImageUpdate;
51  import org.efaps.update.schema.ui.MenuUpdate;
52  import org.efaps.update.schema.ui.SearchUpdate;
53  import org.efaps.update.schema.ui.TableUpdate;
54  import org.efaps.update.schema.user.CompanyUpdate;
55  import org.efaps.update.schema.user.GroupUpdate;
56  import org.efaps.update.schema.user.JAASSystemUpdate;
57  import org.efaps.update.schema.user.RoleUpdate;
58  import org.efaps.util.EFapsException;
59  import org.xml.sax.Attributes;
60  import org.xml.sax.InputSource;
61  import org.xml.sax.SAXException;
62  import org.xml.sax.XMLReader;
63  import org.xml.sax.helpers.DefaultHandler;
64  import org.xml.sax.helpers.XMLReaderFactory;
65  
66  /**
67   * @author The eFaps Team
68   * @version $Id$
69   */
70  public class SaxHandler
71      extends DefaultHandler
72  {
73  
74      /**
75       * Tags used in this Handler.
76       */
77      private final Stack<String> tag = new Stack<String>();
78  
79      /**
80       * Map of attributes for this Handler.
81       */
82      private final Map<String, String> attributes = new HashMap<String, String>();
83  
84      /**
85       * Has this handler been called.
86       */
87      private boolean called = false;
88  
89      /**
90       * Update.
91       */
92      private IUpdate update = null;
93  
94      /**
95       * StringtbUIlder used to hold the content.
96       */
97      private StringBuilder content = null;
98  
99      /**
100      * Url of the file that is parsed.
101      */
102     private URL url = null;
103 
104     /**
105      * @param _url Url of the file to be parsed
106      * @return AbstractUpdate for the file
107      * @throws SAXException on parse exception
108      * @throws IOException on file access error
109      */
110     public IUpdate parse(final URL _url)
111         throws SAXException, IOException
112     {
113         this.url = _url;
114 
115         // einen XML Reader erzeugen
116         final XMLReader reader = XMLReaderFactory.createXMLReader();
117         // den eigenen Sax Content Handler registrieren
118         reader.setContentHandler(this);
119         // unsere Beispiel XML Datei parsen
120 
121         final URLConnection connection = this.url.openConnection();
122         connection.setUseCaches(false);
123         final InputStream stream = connection.getInputStream();
124         reader.parse(new InputSource(stream));
125         stream.close();
126 
127         return this.update;
128     }
129 
130     /**
131      * Getter method for instance variable {@link #update}.
132      *
133      * @return value of instance variable {@link #update}
134      */
135     public IUpdate getUpdate()
136     {
137         return this.update;
138     }
139 
140     /**
141      * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
142      * @param _ch char
143      * @param _start start index
144      * @param _length length
145      * @throws SAXException on error
146      */
147     @Override
148     public void characters(final char[] _ch,
149                            final int _start,
150                            final int _length)
151         throws SAXException
152     {
153 
154         if (_length > 0) {
155             final String contentTmp = new String(_ch, _start, _length);
156             if (!this.called && !this.tag.empty()) {
157                 if (this.content == null) {
158                     this.content = new StringBuilder();
159                 }
160                 this.content.append(contentTmp);
161             }
162         }
163     }
164 
165     /**
166      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
167      *      java.lang.String, java.lang.String)
168      * @param _uri uri
169      * @param _localName local name
170      * @param _qName qualified name
171      * @throws SAXException on error
172      */
173     @Override
174     public void endElement(final String _uri,
175                            final String _localName,
176                            final String _qName)
177         throws SAXException
178     {
179         if (!this.called) {
180             try {
181                 this.update.readXML(this.tag, this.attributes, this.content != null
182                                 ? this.content.toString().trim()
183                                 : null);
184             } catch (final EFapsException e) {
185                 throw new SAXException(e);
186             }
187             this.called = true;
188             this.content = null;
189         }
190 
191         if (!this.tag.isEmpty()) {
192             this.tag.pop();
193         }
194     }
195 
196     /**
197      * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
198      *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
199      * @param _uri uri
200      * @param _localName local name
201      * @param _qName qualified Name
202      * @param _attributes Attributes
203      * @throws SAXException on error
204      */
205     @Override
206     public void startElement(final String _uri,
207                              final String _localName,
208                              final String _qName,
209                              final Attributes _attributes)
210         throws SAXException
211     {
212         if (this.update != null) {
213             if (!this.called && !this.tag.isEmpty()) {
214                 try {
215                     this.update.readXML(this.tag, this.attributes, this.content != null
216                                     ? this.content.toString().trim()
217                                     : null);
218                 } catch (final EFapsException e) {
219                     throw new SAXException(e);
220                 }
221             }
222             this.called = false;
223             this.content = null;
224             this.tag.push(_qName);
225             this.attributes.clear();
226             for (int i = 0; i < _attributes.getLength(); i++) {
227                 this.attributes.put(_attributes.getQName(i), _attributes.getValue(i));
228             }
229         } else {
230             switch (_qName) {
231                 case "access-set":
232                     this.update = new AccessSetUpdate(this.url);
233                     break;
234                 case "access-type":
235                     this.update = new AccessTypeUpdate(this.url);
236                     break;
237                 case "bpm-image":
238                     this.update = new BPMImageUpdate(this.url);
239                     break;
240                 case "common-msgphrase":
241                     this.update = new MsgPhraseUpdate(this.url);
242                     break;
243                 case "common-systemconfiguration":
244                     this.update = new SystemConfigurationUpdate(this.url);
245                     break;
246                 case "datamodel-sqltable":
247                     this.update = new SQLTableUpdate(this.url);
248                     break;
249                 case "datamodel-type":
250                     this.update = new TypeUpdate(this.url);
251                     break;
252                 case "datamodel-dimension":
253                     this.update = new DimensionUpdate(this.url);
254                     break;
255                 case "datamodel-statusgroup":
256                     this.update = new StatusGroupUpdate(this.url);
257                     break;
258                 case "db-store":
259                     this.update = new StoreUpdate(this.url);
260                     break;
261                 case "integration-webdav":
262                     this.update = new WebDAVUpdate(this.url);
263                     break;
264                 case "jasperReport":
265                     this.update = new JasperReportUpdate(this.url);
266                     break;
267                 case "jasper-image":
268                     this.update = new JasperImageUpdate(this.url);
269                     break;
270                 case "numbergenerator":
271                     this.update = new NumberGeneratorUpdate(this.url);
272                     break;
273                 case "ui-command":
274                     this.update = new CommandUpdate(this.url);
275                     break;
276                 case "ui-form":
277                     this.update = new FormUpdate(this.url);
278                     break;
279                 case "ui-image":
280                     this.update = new ImageUpdate(this.url);
281                     break;
282                 case "ui-menu":
283                     this.update = new MenuUpdate(this.url);
284                     break;
285                 case "ui-search":
286                     this.update = new SearchUpdate(this.url);
287                     break;
288                 case "ui-table":
289                     this.update = new TableUpdate(this.url);
290                     break;
291                 case "user-company":
292                     this.update = new CompanyUpdate(this.url);
293                     break;
294                 case "user-jaassystem":
295                     this.update = new JAASSystemUpdate(this.url);
296                     break;
297                 case "user-role":
298                     this.update = new RoleUpdate(this.url);
299                     break;
300                 case "user-group":
301                     this.update = new GroupUpdate(this.url);
302                     break;
303                 case "dbproperties":
304                     this.update = new DBPropertiesUpdate(this.url);
305                     break;
306                 case "help-menu":
307                     this.update = new HelpMenuUpdate(this.url);
308                     break;
309                 case "wiki-image":
310                     this.update = new WikiImageUpdate(this.url);
311                     break;
312                 default:
313                     this.update = new DefaultEmptyUpdate(this.url);
314                     break;
315             }
316         }
317     }
318 }