/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang.grammars.parsers; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Calendar; import java.util.Date; import java.util.Formatter; import java.util.TimeZone; import org.whole.lang.bindings.BindingManagerFactory; import org.whole.lang.bindings.IBindingManager; import org.whole.lang.exceptions.WholeIllegalArgumentException; import org.whole.lang.grammars.model.CompiledPattern; import org.whole.lang.grammars.model.Format; import org.whole.lang.grammars.model.Pattern; import org.whole.lang.grammars.model.RegExp; import org.whole.lang.grammars.reflect.GrammarsEntityDescriptorEnum; import org.whole.lang.grammars.util.GrammarsUtils; import org.whole.lang.matchers.Matcher; import org.whole.lang.model.EnumValue; import org.whole.lang.model.IEntity; import org.whole.lang.parsers.DefaultDataTypePersistenceParser; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.util.BehaviorUtils; import org.whole.lang.util.EntityUtils; import org.whole.lang.util.WholeMessages; import org.whole.lang.visitors.AbstractVisitor; import org.whole.lang.visitors.GenericTraversalFactory; /** * @author Enrico Persiani */ public class GrammarsDefaultDataTypeParser extends DefaultDataTypePersistenceParser { protected GrammarBasedDataTypeParser grammarBasedDataTypeParser; protected GrammarsDefaultDataTypeParser(GrammarBasedDataTypeParser dataTypeParser) { this.grammarBasedDataTypeParser = dataTypeParser; } private IBindingManager bindingManager; protected IBindingManager getBindings() { if (bindingManager == null) bindingManager = BindingManagerFactory.instance.createBindingManager(); return bindingManager; } protected String format(EntityDescriptor<?> ed, Object value) { Format format = grammarBasedDataTypeParser.getDataTerminal(ed).getFormat(); if (EntityUtils.isFragment(format)) { IBindingManager bindings = getBindings(); bindings.wEnterScope(); bindings.wDefValue("self", value); IEntity entity = BehaviorUtils.evaluate(format, 0, bindings); bindings.wExitScope(); return entity.wStringValue(); } else { Formatter formatter = new Formatter(grammarBasedDataTypeParser.getLocale()); return formatter.format(format.getValue(), value).toString(); } } protected String matches(EntityDescriptor<?> ed, String value) { Pattern pattern = grammarBasedDataTypeParser.getDataTerminal(ed).getPattern(); java.util.regex.Pattern compiledPattern = Matcher.matchImpl(GrammarsEntityDescriptorEnum.CompiledPattern, pattern) ? ((CompiledPattern) pattern).getValue() : java.util.regex.Pattern.compile(((RegExp) pattern).getValue()); if (!compiledPattern.matcher(value).matches()) throw new WholeIllegalArgumentException(WholeMessages.no_data_type); return value; } public static String cleanupIntegral(String value) { value = value.trim(); return value.charAt(0) == '+' ? value.substring(1) : value; } public static String cleanupDecimal(String value) { return cleanupIntegral(value).replaceFirst(",", "."); } @Override public boolean parseBoolean(EntityDescriptor<?> ed, String value) { return super.parseBoolean(ed, matches(ed, value)); } @Override public char parseChar(EntityDescriptor<?> ed, String value) { return super.parseChar(ed, matches(ed, value)); } @Override public byte parseByte(EntityDescriptor<?> ed, String value) { return super.parseByte(ed, cleanupIntegral(matches(ed, value))); } @Override public int parseInt(EntityDescriptor<?> ed, String value) { return super.parseInt(ed, cleanupIntegral(matches(ed, value))); } @Override public long parseLong(EntityDescriptor<?> ed, String value) { return super.parseLong(ed, cleanupIntegral(matches(ed, value))); } @Override public short parseShort(EntityDescriptor<?> ed, String value) { return super.parseShort(ed, cleanupIntegral(matches(ed, value))); } @Override public float parseFloat(EntityDescriptor<?> ed, String value) { return super.parseFloat(ed, cleanupDecimal(matches(ed, value))); } @Override public double parseDouble(EntityDescriptor<?> ed, String value) { return super.parseDouble(ed, cleanupDecimal(matches(ed, value))); } @Override public EnumValue parseEnumValue(EntityDescriptor<?> ed, String value) { return GrammarsUtils.parse(value, grammarBasedDataTypeParser.getGrammarURI(), ed).wEnumValue(); } @Override public String parseString(EntityDescriptor<?> ed, String value) { return super.parseString(ed, matches(ed, value)); } @Override public Date parseDate(EntityDescriptor<?> ed, String value) { return super.parseDate(ed, matches(ed, value)); } @Override public Object parseObject(EntityDescriptor<?> ed, String value) { value = matches(ed, value); if (BigDecimal.class.equals(ed.getDataType())) return new BigDecimal(cleanupDecimal(value)); else if (BigInteger.class.equals(ed.getDataType())) return new BigInteger(cleanupIntegral(value)); else return super.parseObject(ed, value); } @Override public String unparseBoolean(EntityDescriptor<?> ed, boolean value) { return format(ed, value); } @Override public String unparseChar(EntityDescriptor<?> ed, char value) { return format(ed, value); } @Override public String unparseByte(EntityDescriptor<?> ed, byte value) { return format(ed, value); } @Override public String unparseShort(EntityDescriptor<?> ed, short value) { return format(ed, value); } @Override public String unparseInt(EntityDescriptor<?> ed, int value) { return format(ed, value); } @Override public String unparseLong(EntityDescriptor<?> ed, long value) { return format(ed, value); } @Override public String unparseFloat(EntityDescriptor<?> ed, float value) { return format(ed, value); } @Override public String unparseDouble(EntityDescriptor<?> ed, double value) { return format(ed, value); } @Override public String unparseEnumValue(EntityDescriptor<?> ed, EnumValue value) { final StringBuilder sb = new StringBuilder(); GenericTraversalFactory.instance.topDown(new AbstractVisitor() { public void visit(IEntity entity) { String text = null; switch (entity.wGetEntityDescriptor().getOrdinal()) { case GrammarsEntityDescriptorEnum.Literal_ord: text = entity.wStringValue(); break; case GrammarsEntityDescriptorEnum.Space_ord: text = grammarBasedDataTypeParser.getSpace(); break; case GrammarsEntityDescriptorEnum.Indent_ord: text = grammarBasedDataTypeParser.getIndent(); break; case GrammarsEntityDescriptorEnum.NewLine_ord: text = grammarBasedDataTypeParser.getNewLine(); break; } if (text != null) { if (sb.length() > 0) sb.append(grammarBasedDataTypeParser.getDelimiter()); sb.append(text); } } }, false).visit(grammarBasedDataTypeParser.getEnumRule(value)); // IEntityIterator<Literal> iterator = IteratorFactory.<Literal>descendantOrSelfMatcherIterator( // grammarBasedDataTypeParser.getEnumRule(value)).usePattern(GrammarsEntityDescriptorEnum.Literal); // if (iterator.hasNext()) // sb.append(iterator.next().getValue()); // while (iterator.hasNext()) { // sb.append(grammarBasedDataTypeParser.getDelimiter()); // sb.append(iterator.next().getValue()); // } return sb.toString(); } @Override public String unparseString(EntityDescriptor<?> ed, String value) { return format(ed, value); } @Override public String unparseDate(EntityDescriptor<?> ed, Date value) { if (Matcher.matchImpl(GrammarsEntityDescriptorEnum.Format, grammarBasedDataTypeParser.getDataTerminal(ed).getFormat())) { //WAS EntityUtils.isImpl(grammarBasedDataTypeParser.getDataTerminal(ed).getFormat())) { Calendar calendar = Calendar.getInstance(grammarBasedDataTypeParser.getLocale()); calendar.setTime(value); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); return format(ed, calendar); } else return format(ed, value); } @Override public String unparseObject(EntityDescriptor<?> ed, Object value) { return format(ed, value); } }