/*******************************************************************************
* Copyright 2013 Naver Business Platform Corp.
*
* 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.handmark.pulltorefresh.configuration.xml;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.handmark.pulltorefresh.library.internal.Assert;
/**
* {@code PullToRefreshConfigXmlParser} does parsing pulltorefresh.xml as {@code XmlPullNode}s
* @author Wonjun Kim
*/
final class PullToRefreshConfigXmlParser extends XmlPullNodeParser<PullToRefreshNode> {
/**
* Repetition limit is only one
*/
private static final int ONLY_ONE_REPEAT = 1;
/**
* Parsed data
*/
private PullToRefreshResult result;
/**
* @param parser Must be not null
*/
public PullToRefreshConfigXmlParser(XmlPullParserWrapper parser) {
super(parser);
}
/**
* Generate a node tree matched by pulltorefresh.xml
* @return root node of a tree
*/
private XmlPullNode init() {
// prepare a result instance
result = new PullToRefreshResult();
// make nodes
XmlPullNode root = new XmlPullNode("PullToRefresh");
XmlPullNode loadingLayouts = new XmlPullNode("LoadingLayouts");
XmlPullNode indicatorLayouts = new XmlPullNode("IndicatorLayouts");
XmlPullNode googleStyleViewLayouts = new XmlPullNode("GoogleStyleViewLayouts");
XmlPullNode googleStyleProgressLayouts = new XmlPullNode("GoogleStyleProgressLayouts");
XmlPullNode loadingLayout = new XmlPullNode("layout",new LayoutNodeCallback(result.loadingLayoutClazzNameMap));
XmlPullNode indicatorLayout = new XmlPullNode("layout",new LayoutNodeCallback(result.indicatorLayoutClazzNameMap));
XmlPullNode googleStyleViewLayout = new XmlPullNode("layout",new LayoutNodeCallback(result.googleStyleViewLayoutClazzNameMap));
XmlPullNode googleStyleProgressLayout = new XmlPullNode("layout",new LayoutNodeCallback(result.googleStyleProgressLayoutClazzNameMap));
// make a tree structure
root.addChildNode(loadingLayouts, ONLY_ONE_REPEAT);
root.addChildNode(indicatorLayouts, ONLY_ONE_REPEAT);
root.addChildNode(googleStyleViewLayouts, ONLY_ONE_REPEAT);
root.addChildNode(googleStyleProgressLayouts, ONLY_ONE_REPEAT);
loadingLayouts.addChildNode(loadingLayout);
indicatorLayouts.addChildNode(indicatorLayout);
googleStyleViewLayouts.addChildNode(googleStyleViewLayout);
googleStyleProgressLayouts.addChildNode(googleStyleProgressLayout);
// return root node
return root;
}
/**
* @return root node of a tree
*/
@Override
protected XmlPullNode generateRootNode() {
return init();
}
/**
* @return Parsed result data as {@code PullToRefreshNode} instance
*/
@Override
protected PullToRefreshNode getResult() {
return new PullToRefreshNode(result.loadingLayoutClazzNameMap, result.indicatorLayoutClazzNameMap, result.googleStyleViewLayoutClazzNameMap, result.googleStyleProgressLayoutClazzNameMap);
}
/**
* Parsed Result to be sent to {@code PullToRefreshNode}
* @author Wonjun Kim
*
*/
private static class PullToRefreshResult {
public final Map<String, String> loadingLayoutClazzNameMap = new HashMap<String, String>();
public final Map<String, String> indicatorLayoutClazzNameMap = new HashMap<String, String>();
public final Map<String, String> googleStyleViewLayoutClazzNameMap = new HashMap<String, String>();
public final Map<String, String> googleStyleProgressLayoutClazzNameMap = new HashMap<String, String>();
}
/**
* Callback of the node 'PullToRefresh/IndicatorLayouts/layout' and 'PullToRefresh/LoadingLayouts/layout'
* @author Wonjun Kim
*
*/
private static class LayoutNodeCallback implements XmlPullNode.XmlPullNodeCallback {
/**
* {@code Map} storing Layouts' information
*/
private Map<String, String> layoutClazzNameMap;
/**
* @param layoutClazzNameMap Must not be null and be clean for which put new values
*/
public LayoutNodeCallback(Map<String, String> layoutClazzNameMap) {
Assert.notNull(layoutClazzNameMap, "Class Map");
this.layoutClazzNameMap = layoutClazzNameMap;
}
/**
* Be called when parser has found 'layout' node at a time
*/
@Override
public void process(XmlPullParser parser) throws XmlPullParserException, IOException {
int attributesCount = parser.getAttributeCount();
String attributeName, attributeValue;
// Iterate attributes!
for (int i = 0; i < attributesCount; ++i) {
attributeName = parser.getAttributeName(i);
attributeValue = parser.getAttributeValue(i);
// The 'name' attribute is as a layout code of each layout's class
if ( "name".equals(attributeName)) {
// Skip if attribute value is null or empty
if ( attributeValue == null || attributeValue.length() == 0 ) {
continue;
}
// Get layout's class name
String clazzName = parser.nextText();
// Insert new class name
layoutClazzNameMap.put(attributeValue, clazzName);
// Do 'break' because nextText() method has been called
break;
}
}
}
}
}