📄 ptsprimitiveserializer.java
字号:
/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-2008 The Android Open Source Project * * 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 com.android.im.imps;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.ArrayList;import java.util.HashMap;import java.util.regex.Matcher;import java.util.regex.Pattern;import com.android.im.imps.ImpsConstants.ImpsVersion;public class PtsPrimitiveSerializer implements PrimitiveSerializer { private final String mPreampleHead; // The ccc is the Transaction-ID in range 0-999 without preceding zero. private static final Pattern sTxIdPattern = Pattern.compile("(0|[1-9]\\d{0,2})"); // If the value of the parameter contains spaces ( ), quotes ("), // commas (,),parentheses (()),equal (=) or ampersand (&) characters, // it SHALL be wrapped with quotes ("). private static final Pattern sCharsToBeQuoted = Pattern.compile("[ \",\\(\\)=&]"); public PtsPrimitiveSerializer(ImpsVersion impsVersion) throws SerializerException { if (impsVersion == ImpsVersion.IMPS_VERSION_12) { mPreampleHead = "WV12"; } else if (impsVersion == ImpsVersion.IMPS_VERSION_13) { mPreampleHead = "WV13"; } else { throw new SerializerException("Unsupported IMPS version"); } } public void serialize(Primitive p, OutputStream out) throws IOException, SerializerException { String txId = p.getTransactionID(); if (txId == null) { if (!ImpsTags.Polling_Request.equals(p.getType())) { throw new SerializerException("null Transaction-ID for non polling request"); } // FIXME: what should this be? Temporarily use 0 txId = "0"; } else { Matcher m = sTxIdPattern.matcher(txId); if (!m.matches()) { throw new SerializerException( "Transaction-ID must be in range 0-999 without preceding zero"); } } // TODO: use buffered writer? Writer writer = new OutputStreamWriter(out, "UTF-8"); writer.write(mPreampleHead); String code = PtsCodes.getTxCode(p.getType()); if (code == null) { throw new SerializerException("Unsupported transaction type " + p.getType()); } writer.write(code); writer.write(txId); if (p.getSessionId() != null) { writer.write(" SI="); writer.write(p.getSessionId()); } PrimitiveElement content = p.getContentElement(); if (content != null && content.getChildCount() > 0) { ArrayList<PrimitiveElement> infoElems = content.getChildren(); ArrayList<String> users = new ArrayList<String>(); ArrayList<String> lists = new ArrayList<String>(); int len = infoElems.size(); for (int i = 0; i < len; i++) { PrimitiveElement elem = infoElems.get(i); String elemName = elem.getTagName(); // workaround for multiple elements if (ImpsTags.User.equals(elemName)) { users.add(elem.getChildContents(ImpsTags.UserID)); continue; } else if (ImpsTags.UserID.equals(elemName)) { users.add(elem.getContents()); continue; } else if (ImpsTags.ContactList.equals(elemName)) { lists.add(elem.getContents()); continue; } String elemCode = PtsCodes.getElementCode(elemName, p.getType()); if (elemCode == null) { throw new SerializerException("Don't know how to encode element " + elemName); } writer.write(' '); writer.write(elemCode); // so far all top level information elements have values. writer.write('='); String value; ElemValueEncoder encoder = ElemValueEncoder.getEncoder(elemName); if (encoder == null) { // default simple value value = escapeValueString(elem.getContents()); } else { value = encoder.encodeValue(p, elem); } if (value == null) { throw new SerializerException("Empty value for element " + elemName); } writer.write(value); } writeMultiValue(writer, PtsCodes.getElementCode(ImpsTags.UserID, p.getType()), users); writeMultiValue(writer, PtsCodes.getElementCode(ImpsTags.ContactList, p.getType()), lists); } writer.close(); } private void writeMultiValue(Writer writer, String code, ArrayList<String> values) throws IOException { if (values.size() == 0) { return; } writer.write(' '); writer.write(code); writer.write('='); if (values.size() == 1) { writer.write(escapeValueString(values.get(0))); } else { writer.write('('); int valueCount = values.size(); for (int i = 0; i < valueCount; i++) { if (i > 0) { writer.write(','); } writer.write(escapeValueString(values.get(i))); } writer.write(')'); } } static String escapeValueString(String contents) { Matcher m = sCharsToBeQuoted.matcher(contents); if (m.find()) { if (contents.indexOf('"') != -1) { contents = contents.replace("\"", "\"\""); } return "\"" + contents + "\""; } return contents; } static void appendPairValue(StringBuilder buf, String first, String second) { buf.append('('); if (first != null) { buf.append(first); } buf.append(','); buf.append(second); buf.append(')'); } /** * Appends a name and value pair like "(<name>,<value>)". */ static boolean appendNameAndValue(StringBuilder buf, String name, String value, HashMap<String, String> nameCodes, HashMap<String, String> valueCodes, boolean ignoreUnsupportedValue) { String nameCode = nameCodes.get(name); if (nameCode == null) { ImpsLog.log("PTS: Ignoring value " + name); return false; } String valueCode = null; if (valueCodes != null) { valueCode = valueCodes.get(value); } if (valueCode != null) { value = valueCode; } else { if (ignoreUnsupportedValue) { return false; } value = escapeValueString(value); } appendPairValue(buf, nameCode, value); return true; } static abstract class ElemValueEncoder { public abstract String encodeValue(Primitive p, PrimitiveElement elem) throws SerializerException; public static ElemValueEncoder getEncoder(String elemName) { return sEncoders.get(elemName); } private static HashMap<String, ElemValueEncoder> sEncoders; static { sEncoders = new HashMap<String, ElemValueEncoder>(); sEncoders.put(ImpsTags.ClientID, new ClientIdEncoder()); sEncoders.put(ImpsTags.CapabilityList, new CapabilityEncoder()); sEncoders.put(ImpsTags.Functions, new ServiceTreeEncoder()); sEncoders.put(ImpsTags.Result, new ResultEncoder()); sEncoders.put(ImpsTags.ContactListProperties, new ProperitiesEncoder( PtsCodes.sContactListPropsToCode)); sEncoders.put(ImpsTags.PresenceSubList, new PresenceSubListEncoder()); ElemValueEncoder nickListEncoder = new NickListEncoder(); sEncoders.put(ImpsTags.NickList, nickListEncoder); sEncoders.put(ImpsTags.AddNickList, nickListEncoder); sEncoders.put(ImpsTags.RemoveNickList, nickListEncoder); } } static class PresenceSubListEncoder extends ElemValueEncoder { private boolean mEncodePresenceValue; @Override public String encodeValue(Primitive p, PrimitiveElement elem) throws SerializerException { if (elem.getChildCount() == 0) { throw new SerializerException("No presence in the PresenceSubList"); } StringBuilder buf = new StringBuilder(); mEncodePresenceValue = ImpsTags.UpdatePresence_Request.equals(p.getType()); ArrayList<PrimitiveElement> presences = elem.getChildren(); int presenceCount = presences.size(); if (presenceCount == 1) { if (mEncodePresenceValue) { // Append an extra pair of braces according to the Spec buf.append('('); encodePresence(buf, presences.get(0)); buf.append(')'); } else { encodePresence(buf, presences.get(0)); } } else { buf.append('('); for (int i = 0; i < presenceCount; i++) { if (i > 0) { buf.append(','); } encodePresence(buf, presences.get(i)); } buf.append(')'); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -