Java tutorial
/******************************************************************************* * Crown Copyright (c) 2006, 2012, Copyright (c) 2006, 2008 Kestral Computing P/L. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Kestral Computing P/L - initial implementation * Werner Keil - added static imports *******************************************************************************/ package org.eclipse.uomo.ucum.parsers; import static org.eclipse.uomo.ucum.model.ConceptKind.*; import static org.xmlpull.v1.XmlPullParser.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.text.ParseException; import java.util.Date; import org.apache.commons.lang.StringUtils; import org.eclipse.uomo.core.UOMoException; import org.eclipse.uomo.ucum.internal.Messages; import org.eclipse.uomo.ucum.model.BaseUnit; import org.eclipse.uomo.ucum.model.DefinedUnit; import org.eclipse.uomo.ucum.model.Prefix; import org.eclipse.uomo.ucum.model.UcumModel; import org.eclipse.uomo.ucum.model.Value; import org.eclipse.uomo.util.Parser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.SimpleDateFormat; /** * Parses the file ucum-essense.xml * * @author Grahame Grieve * @author Werner Keil */ public class DefinitionParser implements Parser<String, UcumModel> { public UcumModel parse(String filename) throws UOMoException { try { return parse(new FileInputStream(new File(filename))); } catch (XmlPullParserException x) { throw new UOMoException(x); } catch (ParseException p) { throw new UOMoException(p); } catch (IOException i) { throw new UOMoException(i); } } public UcumModel parse(InputStream stream) throws XmlPullParserException, IOException, ParseException { XmlPullParserFactory factory = XmlPullParserFactory .newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null); factory.setNamespaceAware(true); XmlPullParser xpp = factory.newPullParser(); xpp.setInput(stream, null); int eventType = xpp.next(); if (eventType != START_TAG) throw new XmlPullParserException(Messages.DefinitionParser_0); if (!xpp.getName().equals("root")) //$NON-NLS-1$ throw new XmlPullParserException( Messages.DefinitionParser_2 + xpp.getName() + Messages.DefinitionParser_3); final DateFormat fmt = new SimpleDateFormat(Messages.DefinitionParser_DateFormat); Date date = fmt.parse(xpp.getAttributeValue(null, "revision-date").substring(7, 32)); //$NON-NLS-1$ UcumModel root = new UcumModel(xpp.getAttributeValue(null, "version"), //$NON-NLS-1$ xpp.getAttributeValue(null, "revision"), date); //$NON-NLS-1$ xpp.next(); while (xpp.getEventType() != END_TAG) { if (xpp.getEventType() == TEXT) { if (StringUtils.isWhitespace(xpp.getText())) xpp.next(); else throw new XmlPullParserException(Messages.DefinitionParser_8 + xpp.getText()); } else if (xpp.getName().equals(PREFIX.visibleName())) root.getPrefixes().add(parsePrefix(xpp)); else if (xpp.getName().equals(BASEUNIT.visibleName())) root.getBaseUnits().add(parseBaseUnit(xpp)); else if (xpp.getName().equals(UNIT.visibleName())) root.getDefinedUnits().add(parseUnit(xpp)); else throw new XmlPullParserException(Messages.DefinitionParser_9 + xpp.getName()); } return root; } private DefinedUnit parseUnit(XmlPullParser xpp) throws XmlPullParserException, IOException { DefinedUnit unit = new DefinedUnit(xpp.getAttributeValue(null, "Code"), //$NON-NLS-1$ xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ unit.setMetric("yes".equals(xpp.getAttributeValue(null, "isMetric"))); //$NON-NLS-1$ //$NON-NLS-2$ unit.setSpecial("yes".equals(xpp.getAttributeValue(null, "isSpecial"))); //$NON-NLS-1$ //$NON-NLS-2$ unit.setClass_(xpp.getAttributeValue(null, "class")); //$NON-NLS-1$ xpp.next(); skipWhitespace(xpp); while (xpp.getEventType() == START_TAG && "name".equals(xpp.getName())) //$NON-NLS-1$ unit.getNames().add(readElement(xpp, "name", UNIT.visibleName() + " " + unit.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ if (xpp.getEventType() == START_TAG && "printSymbol".equals(xpp.getName())) //$NON-NLS-1$ unit.setPrintSymbol(readElement(xpp, "printSymbol", UNIT.visibleName() + " " + unit.getCode(), true)); //$NON-NLS-1$ //$NON-NLS-2$ unit.setProperty(readElement(xpp, "property", UNIT.visibleName() + " " + unit.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ unit.setValue(parseValue(xpp, "unit " + unit.getCode())); //$NON-NLS-1$ xpp.next(); skipWhitespace(xpp); return unit; } private Value<?> parseValue(XmlPullParser xpp, String context) throws XmlPullParserException, IOException { checkAtElement(xpp, "value", context); //$NON-NLS-1$ BigDecimal val = null; if (xpp.getAttributeValue(null, "value") != null) //$NON-NLS-1$ try { val = new BigDecimal(xpp.getAttributeValue(null, "value")); //$NON-NLS-1$ } catch (NumberFormatException e) { throw new XmlPullParserException( Messages.DefinitionParser_29 + context + Messages.DefinitionParser_30 + e.getMessage()); } @SuppressWarnings("rawtypes") Value<?> value = new Value(xpp.getAttributeValue(null, "Unit"), xpp.getAttributeValue(null, "UNIT"), val); //$NON-NLS-1$ //$NON-NLS-2$ value.setText(readElement(xpp, "value", context, true)); //$NON-NLS-1$ return value; } private BaseUnit parseBaseUnit(XmlPullParser xpp) throws XmlPullParserException, IOException { BaseUnit base = new BaseUnit(xpp.getAttributeValue(null, "Code"), xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ //$NON-NLS-2$ base.setDim(xpp.getAttributeValue(null, "dim").charAt(0)); //$NON-NLS-1$ xpp.next(); skipWhitespace(xpp); base.getNames().add(readElement(xpp, "name", BASEUNIT.visibleName() + " " + base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ base.setPrintSymbol(readElement(xpp, "printSymbol", BASEUNIT.visibleName() + " " + base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ base.setProperty(readElement(xpp, "property", BASEUNIT.visibleName() + " " + base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ xpp.next(); skipWhitespace(xpp); return base; } private Prefix parsePrefix(XmlPullParser xpp) throws XmlPullParserException, IOException { Prefix prefix = new Prefix(xpp.getAttributeValue(null, "Code"), xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ //$NON-NLS-2$ xpp.next(); skipWhitespace(xpp); prefix.getNames().add(readElement(xpp, "name", PREFIX.visibleName() + " " + prefix.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ prefix.setPrintSymbol( readElement(xpp, "printSymbol", PREFIX.visibleName() + " " + prefix.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$ checkAtElement(xpp, "value", PREFIX.visibleName() + " " + prefix.getCode()); //$NON-NLS-1$ //$NON-NLS-2$ prefix.setValue(new BigDecimal(xpp.getAttributeValue(null, "value"))); //$NON-NLS-1$ readElement(xpp, "value", PREFIX.visibleName() + " " + prefix.getCode(), true); //$NON-NLS-1$ //$NON-NLS-2$ xpp.next(); skipWhitespace(xpp); return prefix; } private String readElement(XmlPullParser xpp, String name, String context, boolean complex) throws XmlPullParserException, IOException { checkAtElement(xpp, name, context); xpp.next(); skipWhitespace(xpp); String val = null; if (complex) { val = readText(xpp); } else if (xpp.getEventType() == TEXT) { val = xpp.getText(); xpp.next(); skipWhitespace(xpp); } if (xpp.getEventType() != END_TAG) { throw new XmlPullParserException(Messages.DefinitionParser_54 + context); } xpp.next(); skipWhitespace(xpp); return val; } private String readText(XmlPullParser xpp) throws XmlPullParserException, IOException { StringBuilder bldr = new StringBuilder(); while (xpp.getEventType() != END_TAG) { if (xpp.getEventType() == TEXT) { bldr.append(xpp.getText()); xpp.next(); } else { xpp.next(); bldr.append(readText(xpp)); xpp.next(); skipWhitespace(xpp); } } return bldr.toString(); } private void skipWhitespace(XmlPullParser xpp) throws XmlPullParserException, IOException { while (xpp.getEventType() == TEXT && StringUtils.isWhitespace(xpp.getText())) xpp.next(); } private void checkAtElement(XmlPullParser xpp, String name, String context) throws XmlPullParserException { if (xpp.getEventType() != START_TAG) throw new XmlPullParserException(Messages.DefinitionParser_55 + name + Messages.DefinitionParser_56 + Integer.toString(xpp.getEventType()) + Messages.DefinitionParser_57 + context); if (!xpp.getName().equals(name)) throw new XmlPullParserException(Messages.DefinitionParser_58 + name + Messages.DefinitionParser_59 + xpp.getName() + Messages.DefinitionParser_60 + context); } }