KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > server > SyncMLCanonizer


1 /**
2  * Copyright (C) 2003-2005 Funambol
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package sync4j.server;
20
21 import java.io.Serializable JavaDoc;
22 import java.util.logging.Logger JavaDoc;
23 import java.util.logging.Level JavaDoc;
24
25 import sync4j.framework.logging.Sync4jLogger;
26
27 import sync4j.framework.core.SyncML;
28 import sync4j.framework.core.Sync4jException;
29
30 import org.apache.commons.lang.StringUtils;
31
32 /**
33  * This class is used to transform the input message into the canonical form.
34  *
35  * @version $Id: SyncMLCanonizer.java,v 1.7 2005/03/02 20:57:39 harrie Exp $
36  */

37 public class SyncMLCanonizer implements Serializable JavaDoc {
38
39     // ------------------------------------------------------------ Private data
40
private static final Logger JavaDoc log = Sync4jLogger.getLogger("engine");
41     
42     // ------------------------------------------------------------ Constructors
43
public SyncMLCanonizer() {
44     }
45
46     // ---------------------------------------------------------- Public methods
47

48     /**
49      * Canonizes outgoing messages.
50      *
51      * @param message the input XML message
52      *
53      * @return message the input XML message canonized
54      **/

55     public String JavaDoc canonizeOutput(String JavaDoc message) {
56         if (log.isLoggable(Level.FINEST)) {
57             log.finest("Starting output canonization");
58         }
59         
60         message = devInfHandler(message);
61         
62         return metInfNamespaceHandler(message);
63     }
64     
65     /**
66      * The input message must be canonized every time before calling the XML-Java
67      * mapping tool (JiBX) that parses the input and generates the SyncML object.
68      *
69      * @param message the XML input message
70      *
71      * @return the canonized XML input message
72      **/

73     public String JavaDoc canonizeInput(String JavaDoc message) {
74         if (log.isLoggable(Level.FINEST)) {
75             log.finest("Starting input canonization");
76         }
77         
78         message = fixXMLVersion(message);
79         
80         return message;
81     }
82    
83     /**
84      * Replace the '&' with "&" within the message.
85      *
86      * @param message the original message xml
87      *
88      * @return the updated message
89      */

90     private String JavaDoc replaceEntity(String JavaDoc message) {
91         return StringUtils.replace(message, "&", "&");
92     }
93     
94     /**
95      * This is a temporary solution in order to obviate to a JiBX bug: it does
96      * not allow to declare the namespace to level of structure.
97      *
98      * @param msg the server response
99      *
100      * @return the response with namespace correctly added into MetInf element
101      */

102     private String JavaDoc metInfNamespaceHandler(String JavaDoc msg) {
103         int s = 0;
104         int e = 0;
105         
106         StringBuffer JavaDoc response = new StringBuffer JavaDoc();
107         while (( e = msg.indexOf("<Meta", s)) >= 0) {
108             
109             response = response.append(msg.substring(s, e));
110             
111             int a = msg.indexOf("</Meta>", e);
112             String JavaDoc meta = msg.substring(e, a);
113             
114             meta = meta.replaceAll("<MetInf>" , "<MetInf xmlns='syncml:metinf'>");
115             meta = meta.replaceAll("<Type>" , "<Type xmlns='syncml:metinf'>");
116             meta = meta.replaceAll("<Format>" , "<Format xmlns='syncml:metinf'>");
117             meta = meta.replaceAll("<Mark>" , "<Mark xmlns='syncml:metinf'>");
118             meta = meta.replaceAll("<Size>" , "<Size xmlns='syncml:metinf'>");
119             meta = meta.replaceAll("<Anchor>" , "<Anchor xmlns='syncml:metinf'>");
120             meta = meta.replaceAll("<Version>", "<Version xmlns='syncml:metinf'>");
121             meta = meta.replaceAll("<NextNonce>" , "<NextNonce xmlns='syncml:metinf'>");
122             meta = meta.replaceAll("<MaxMsgSize>", "<MaxMsgSize xmlns='syncml:metinf'>");
123             meta = meta.replaceAll("<MaxObjSize>", "<MaxObjSize xmlns='syncml:metinf'>");
124             meta = meta.replaceAll("<EMI>" , "<EMI xmlns='syncml:metinf'>");
125             meta = meta.replaceAll("<Mem>" , "<Mem xmlns='syncml:metinf'>");
126             
127             s = a + 7;
128             response.append(meta).append("</Meta>");
129         }
130         return response.append(msg.substring(s, msg.length())).toString();
131     }
132     
133     private String JavaDoc devInfHandler(String JavaDoc msg) {
134         
135         msg = StringUtils.replaceOnce(msg, "<UTC></UTC>", "<UTC/>");
136         msg = StringUtils.replaceOnce(msg, "<SupportLargeObjs></SupportLargeObjs>", "<SupportLargeObjs/>");
137         msg = StringUtils.replaceOnce(msg, "<SupportNumberOfChanges></SupportNumberOfChanges>", "<SupportNumberOfChanges/>");
138         
139         
140         msg = StringUtils.replaceOnce(msg, "<MoreData></MoreData>", "<MoreData/>");
141         
142         return msg;
143     }
144     
145     /**
146      * Replaces the XML version from any value to "1.0", which is the version
147      * supported by our parser. This should not cause any problem since SyncML
148      * does not use any XML 1.1 specific feature.
149      *
150      * @param msg the message to process
151      *
152      * @return the processed message
153      */

154     private String JavaDoc fixXMLVersion(String JavaDoc msg) {
155         
156         if (!msg.startsWith("<?xml")) {
157             return msg;
158         }
159         
160         int e = msg.indexOf("?>");
161         if (e < 0) {
162             return msg;
163         }
164         
165         String JavaDoc prolog = msg.substring(0, e+2);
166         
167         log.finest("prolog: " + prolog);
168         
169         prolog = prolog.replaceFirst("version(\\s)*=[\"'][^\"']+[\"']", "version=\"1.0\"");
170         
171         return prolog + msg.substring(e+2);
172         
173     }
174 }
175
176
177
Popular Tags