Initial Contribution
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 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.layoutlib.utils;
|
||||
|
||||
import com.android.layoutlib.api.IResourceValue;
|
||||
|
||||
public class ResourceValue implements IResourceValue {
|
||||
private final String mType;
|
||||
private final String mName;
|
||||
private String mValue = null;
|
||||
private final boolean mIsFramwork;
|
||||
|
||||
public ResourceValue(String type, String name, boolean isFramwork) {
|
||||
mType = type;
|
||||
mName = name;
|
||||
mIsFramwork = isFramwork;
|
||||
}
|
||||
|
||||
public ResourceValue(String type, String name, String value, boolean isFramework) {
|
||||
mType = type;
|
||||
mName = name;
|
||||
mValue = value;
|
||||
mIsFramwork = isFramework;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public final String getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public final void setValue(String value) {
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public void replaceWith(ResourceValue value) {
|
||||
mValue = value.mValue;
|
||||
}
|
||||
|
||||
public boolean isFramework() {
|
||||
return mIsFramwork;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 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.layoutlib.utils;
|
||||
|
||||
import com.android.layoutlib.api.IResourceValue;
|
||||
import com.android.layoutlib.api.IStyleResourceValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class StyleResourceValue extends ResourceValue implements IStyleResourceValue {
|
||||
|
||||
private String mParentStyle = null;
|
||||
private HashMap<String, IResourceValue> mItems = new HashMap<String, IResourceValue>();
|
||||
|
||||
public StyleResourceValue(String type, String name, boolean isFramework) {
|
||||
super(type, name, isFramework);
|
||||
}
|
||||
|
||||
public StyleResourceValue(String type, String name, String parentStyle, boolean isFramework) {
|
||||
super(type, name, isFramework);
|
||||
mParentStyle = parentStyle;
|
||||
}
|
||||
|
||||
public String getParentStyle() {
|
||||
return mParentStyle;
|
||||
}
|
||||
|
||||
public IResourceValue findItem(String name) {
|
||||
return mItems.get(name);
|
||||
}
|
||||
|
||||
public void addItem(IResourceValue value) {
|
||||
mItems.put(value.getName(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceWith(ResourceValue value) {
|
||||
super.replaceWith(value);
|
||||
|
||||
if (value instanceof StyleResourceValue) {
|
||||
mItems.clear();
|
||||
mItems.putAll(((StyleResourceValue)value).mItems);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 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.layoutlib.utils;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* SAX handler to parser value resource files.
|
||||
*/
|
||||
public final class ValueResourceParser extends DefaultHandler {
|
||||
|
||||
// TODO: reuse definitions from somewhere else.
|
||||
private final static String NODE_RESOURCES = "resources";
|
||||
private final static String NODE_ITEM = "item";
|
||||
private final static String ATTR_NAME = "name";
|
||||
private final static String ATTR_TYPE = "type";
|
||||
private final static String ATTR_PARENT = "parent";
|
||||
|
||||
// Resource type definition
|
||||
private final static String RES_STYLE = "style";
|
||||
private final static String RES_ATTR = "attr";
|
||||
|
||||
private final static String DEFAULT_NS_PREFIX = "android:";
|
||||
private final static int DEFAULT_NS_PREFIX_LEN = DEFAULT_NS_PREFIX.length();
|
||||
|
||||
public interface IValueResourceRepository {
|
||||
void addResourceValue(String resType, ResourceValue value);
|
||||
}
|
||||
|
||||
private boolean inResources = false;
|
||||
private int mDepth = 0;
|
||||
private StyleResourceValue mCurrentStyle = null;
|
||||
private ResourceValue mCurrentValue = null;
|
||||
private IValueResourceRepository mRepository;
|
||||
private final boolean mIsFramework;
|
||||
|
||||
public ValueResourceParser(IValueResourceRepository repository, boolean isFramework) {
|
||||
mRepository = repository;
|
||||
mIsFramework = isFramework;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
if (mCurrentValue != null) {
|
||||
mCurrentValue.setValue(trimXmlWhitespaces(mCurrentValue.getValue()));
|
||||
}
|
||||
|
||||
if (inResources && qName.equals(NODE_RESOURCES)) {
|
||||
inResources = false;
|
||||
} else if (mDepth == 2) {
|
||||
mCurrentValue = null;
|
||||
mCurrentStyle = null;
|
||||
} else if (mDepth == 3) {
|
||||
mCurrentValue = null;
|
||||
}
|
||||
|
||||
mDepth--;
|
||||
super.endElement(uri, localName, qName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||
throws SAXException {
|
||||
try {
|
||||
mDepth++;
|
||||
if (inResources == false && mDepth == 1) {
|
||||
if (qName.equals(NODE_RESOURCES)) {
|
||||
inResources = true;
|
||||
}
|
||||
} else if (mDepth == 2 && inResources == true) {
|
||||
String type;
|
||||
|
||||
// if the node is <item>, we get the type from the attribute "type"
|
||||
if (NODE_ITEM.equals(qName)) {
|
||||
type = attributes.getValue(ATTR_TYPE);
|
||||
} else {
|
||||
// the type is the name of the node.
|
||||
type = qName;
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
if (RES_ATTR.equals(type) == false) {
|
||||
// get the resource name
|
||||
String name = attributes.getValue(ATTR_NAME);
|
||||
if (name != null) {
|
||||
if (RES_STYLE.equals(type)) {
|
||||
String parent = attributes.getValue(ATTR_PARENT);
|
||||
mCurrentStyle = new StyleResourceValue(type, name, parent, mIsFramework);
|
||||
mRepository.addResourceValue(type, mCurrentStyle);
|
||||
} else {
|
||||
mCurrentValue = new ResourceValue(type, name, mIsFramework);
|
||||
mRepository.addResourceValue(type, mCurrentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mDepth == 3 && mCurrentStyle != null) {
|
||||
// get the resource name
|
||||
String name = attributes.getValue(ATTR_NAME);
|
||||
if (name != null) {
|
||||
// the name can, in some cases, contain a prefix! we remove it.
|
||||
if (name.startsWith(DEFAULT_NS_PREFIX)) {
|
||||
name = name.substring(DEFAULT_NS_PREFIX_LEN);
|
||||
}
|
||||
|
||||
mCurrentValue = new ResourceValue(null, name, mIsFramework);
|
||||
mCurrentStyle.addItem(mCurrentValue);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
super.startElement(uri, localName, qName, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
if (mCurrentValue != null) {
|
||||
String value = mCurrentValue.getValue();
|
||||
if (value == null) {
|
||||
mCurrentValue.setValue(new String(ch, start, length));
|
||||
} else {
|
||||
mCurrentValue.setValue(value + new String(ch, start, length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String trimXmlWhitespaces(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// look for carriage return and replace all whitespace around it by just 1 space.
|
||||
int index;
|
||||
|
||||
while ((index = value.indexOf('\n')) != -1) {
|
||||
// look for whitespace on each side
|
||||
int left = index - 1;
|
||||
while (left >= 0) {
|
||||
if (Character.isWhitespace(value.charAt(left))) {
|
||||
left--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int right = index + 1;
|
||||
int count = value.length();
|
||||
while (right < count) {
|
||||
if (Character.isWhitespace(value.charAt(right))) {
|
||||
right++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove all between left and right (non inclusive) and replace by a single space.
|
||||
String leftString = null;
|
||||
if (left >= 0) {
|
||||
leftString = value.substring(0, left + 1);
|
||||
}
|
||||
String rightString = null;
|
||||
if (right < count) {
|
||||
rightString = value.substring(right);
|
||||
}
|
||||
|
||||
if (leftString != null) {
|
||||
value = leftString;
|
||||
if (rightString != null) {
|
||||
value += " " + rightString;
|
||||
}
|
||||
} else {
|
||||
value = rightString != null ? rightString : "";
|
||||
}
|
||||
}
|
||||
|
||||
// now we un-escape the string
|
||||
int length = value.length();
|
||||
char[] buffer = value.toCharArray();
|
||||
|
||||
for (int i = 0 ; i < length ; i++) {
|
||||
if (buffer[i] == '\\') {
|
||||
if (buffer[i+1] == 'u') {
|
||||
// this is unicode char.
|
||||
int unicodeChar = Integer.parseInt(new String(buffer, i+2, 4), 16);
|
||||
|
||||
// put the unicode char at the location of the \
|
||||
buffer[i] = (char)unicodeChar;
|
||||
|
||||
// offset the rest of the buffer since we go from 6 to 1 char
|
||||
if (i + 6 < buffer.length) {
|
||||
System.arraycopy(buffer, i+6, buffer, i+1, length - i - 6);
|
||||
}
|
||||
length -= 5;
|
||||
} else {
|
||||
if (buffer[i+1] == 'n') {
|
||||
// replace the 'n' char with \n
|
||||
buffer[i+1] = '\n';
|
||||
}
|
||||
|
||||
// offset the buffer to erase the \
|
||||
System.arraycopy(buffer, i+1, buffer, i, length - i - 1);
|
||||
length--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new String(buffer, 0, length);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user