1/*
2 * Copyright (C) 2012 The Android Open Source Project
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
17package com.android.inputmethod.latin.maketext;
18
19import org.xml.sax.Attributes;
20import org.xml.sax.SAXException;
21import org.xml.sax.ext.DefaultHandler2;
22
23import java.io.IOException;
24import java.io.InputStream;
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.HashMap;
28import java.util.List;
29import java.util.Map;
30
31import javax.xml.parsers.ParserConfigurationException;
32import javax.xml.parsers.SAXParser;
33import javax.xml.parsers.SAXParserFactory;
34
35public class StringResourceMap {
36    // String resource list.
37    private final List<StringResource> mResources;
38    // Name to string resource map.
39    private final Map<String, StringResource> mResourcesMap;
40
41    public StringResourceMap(final InputStream is) {
42        final StringResourceHandler handler = new StringResourceHandler();
43        final SAXParserFactory factory = SAXParserFactory.newInstance();
44        factory.setNamespaceAware(true);
45        try {
46            final SAXParser parser = factory.newSAXParser();
47            // In order to get comment tag.
48            parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
49            parser.parse(is, handler);
50        } catch (ParserConfigurationException e) {
51        } catch (SAXException e) {
52            throw new RuntimeException(e.getMessage());
53        } catch (IOException e) {
54        }
55
56        mResources = Collections.unmodifiableList(handler.mResources);
57        final HashMap<String,StringResource> map = new HashMap<String,StringResource>();
58        for (final StringResource res : mResources) {
59            map.put(res.mName, res);
60        }
61        mResourcesMap = map;
62    }
63
64    public List<StringResource> getResources() {
65        return mResources;
66    }
67
68    public boolean contains(final String name) {
69        return mResourcesMap.containsKey(name);
70    }
71
72    public StringResource get(final String name) {
73        return mResourcesMap.get(name);
74    }
75
76    static class StringResourceHandler extends DefaultHandler2 {
77        private static final String TAG_RESOURCES = "resources";
78        private static final String TAG_STRING = "string";
79        private static final String ATTR_NAME = "name";
80
81        final ArrayList<StringResource> mResources = new ArrayList<StringResource>();
82
83        private String mName;
84        private final StringBuilder mValue = new StringBuilder();
85        private final StringBuilder mComment = new StringBuilder();
86
87        private void init() {
88            mName = null;
89            mComment.setLength(0);
90        }
91
92        @Override
93        public void comment(char[] ch, int start, int length) {
94            mComment.append(ch, start, length);
95            if (ch[start + length - 1] != '\n') {
96                mComment.append('\n');
97            }
98        }
99
100        @Override
101        public void startElement(String uri, String localName, String qName, Attributes attr) {
102            if (TAG_RESOURCES.equals(localName)) {
103                init();
104            } else if (TAG_STRING.equals(localName)) {
105                mName = attr.getValue(ATTR_NAME);
106                mValue.setLength(0);
107            }
108        }
109
110        @Override
111        public void characters(char[] ch, int start, int length) {
112            mValue.append(ch, start, length);
113        }
114
115        @Override
116        public void endElement(String uri, String localName, String qName) throws SAXException {
117            if (TAG_STRING.equals(localName)) {
118                if (mName == null)
119                    throw new SAXException(TAG_STRING + " doesn't have name");
120                final String comment = mComment.length() > 0 ? mComment.toString() : null;
121                String value = mValue.toString();
122                if (value.startsWith("\"") && value.endsWith("\"")) {
123                    // Trim surroundings double quote.
124                    value = value.substring(1, value.length() - 1);
125                }
126                mResources.add(new StringResource(mName, value, comment));
127                init();
128            }
129        }
130    }
131}
132