/****************************************************************************** * Copyright (C) 2015 iDempiere * * Product: iDempiere ERP & CRM Smart Business Solution * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *****************************************************************************/ package org.idempiere.util; import java.util.Iterator; import java.util.regex.Pattern; /** * This class help to parse ordered configuration.
* For example, problem in IDEMPIERE-2296. Some wish priority of "default value" is higher than "user value preference" * and some other wish the reverse of that.
* It is better to define 1 is representative for "default value" and 2 is representative for "user value preference", * and in configuration just set 12 or 21 for an ordered configuration. *

* This class will help by providing method similar to Iterable and it also provide validation for duplicate value such as 221 or 211. * @author hieplq * */ public class ParseSeq implements Iterable { public static String MSG_NOT_NULL = "configuration must is a not null or non empty string"; public static String MSG_ONLY_NUNBER = "your value must contain only number character"; public static String MSG_CONTAIN_DUP = "your value must contain non duplicate character"; /** * Init an Ordered configuration by parsing configuration value.
* Configuration can contain duplicate value or contain only number.
* When detected a wrong configuration value, will throw {@link IllegalArgumentException}. * * @param orderConfiguration configuration value such as "5ry76t" * @param allowDupCharacter if false configuration value as "1245648" is invalid since "4" is duplicate * @param onlyNumber configuration value contain only number */ private ParseSeq (String orderConfiguration, boolean allowDupCharacter, boolean onlyNumber){ parseValue(orderConfiguration, allowDupCharacter, onlyNumber); this.orderConfiguration = orderConfiguration; } private String orderConfiguration; /** * pattern matching a string only number character */ private Pattern regCheckOnlyNumber = Pattern.compile("\\d+"); /** * pattern find duplicate character in string */ private Pattern regCheckDupChar = Pattern.compile("(\\w).*\\1"); /** * validate input string * @param orderConfiguration * @param allowDupCharacter * @param onlyNumber */ protected void parseValue (String orderConfiguration, boolean allowDupCharacter, boolean onlyNumber){ if (orderConfiguration == null || orderConfiguration.length() == 0) throw new IllegalArgumentException(MSG_NOT_NULL); if (onlyNumber && !regCheckOnlyNumber.matcher(orderConfiguration).matches()){ throw new IllegalArgumentException(MSG_ONLY_NUNBER); } if (!allowDupCharacter && regCheckDupChar.matcher(orderConfiguration).find()){ throw new IllegalArgumentException(MSG_CONTAIN_DUP); } } @Override public Iterator iterator() { return new IteratorOrderUtil (orderConfiguration); } /** * constructor maybe become complicate by add more validate (don't allow space, don't allow special,...) * use get for simple when init this object, don't need add try catch block when use * @param orderConfiguration * @return null when input string isn't suitable */ public static ParseSeq getNumberOrder (String orderConfiguration){ ParseSeq numberOrder = null; try{ numberOrder = new ParseSeq(orderConfiguration, false, true); }catch (IllegalArgumentException ex){ return null; } return numberOrder; } /** * support class for iterator throw start to end of order * @author hieplq * */ public static class IteratorOrderUtil implements Iterator{ private String orderConfiguration; int currentIndex = -1; public IteratorOrderUtil (String orderConfiguration){ this.orderConfiguration = orderConfiguration; } @Override public boolean hasNext() { return currentIndex < orderConfiguration.length() - 1; } @Override public Character next() { currentIndex++; return orderConfiguration.charAt(currentIndex); } /** * don't support this function */ @Override public void remove() { throw new UnsupportedOperationException("Don't support this action"); } } /** * run test for utility * @param args */ public static void main(String[] args) { ParseSeq test = null; try{ test = new ParseSeq ("e345", true, true); System.out.printf("Test for check only number case has non number:%s", false); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check only number case has non number:%1$s", MSG_ONLY_NUNBER.equals(ex.getMessage())); System.out.println(); } try{ test = new ParseSeq ("345", true, true); System.out.printf("Test for check only number case normal:%1$s", true); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check only number case normal:%1$s", false); System.out.println(); } try{ test = new ParseSeq ("3545", true, true); System.out.printf("Test for check dup character case allow:%1$s", true); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check dup character case allow:%1$s", false); System.out.println(); } try{ test = new ParseSeq ("3afa5", true, false); System.out.printf("Test for check dup character case allow:%1$s", true); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check dup character case allow:%1$s", false); System.out.println(); } try{ test = new ParseSeq ("3545", false, false); System.out.printf("Test for check dup character case disallow:%1$s", false); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check dup character case disallow:%1$s", MSG_CONTAIN_DUP.equals(ex.getMessage())); System.out.println(); } try{ test = new ParseSeq ("3afa5", false, false); System.out.printf("Test for check dup character case disallow:%1$s", false); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check dup character case disallow:%1$s", MSG_CONTAIN_DUP.equals(ex.getMessage())); System.out.println(); } try{ test = new ParseSeq ("3sfa5", false, false); System.out.printf("Test for check dup character case disallow:%1$s", true); System.out.println(); }catch (IllegalArgumentException ex){ System.out.printf("Test for check dup character case disallow:%1$s", false); System.out.println(); } test = ParseSeq.getNumberOrder("4567289"); System.out.printf("travel configuration:%1$s", "4567289"); System.out.println(); for (Character ch : test){ System.out.print(ch); } } @Override public String toString() { return "OrderConfiguration=" + orderConfiguration; } }