/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.kie.workbench.common.forms.commons.rendering.shared.util.masks; import java.util.ArrayList; import java.util.List; import org.jboss.errai.common.client.api.Assert; /** * Generates String representations for Objects based on a mask String. That mask defines the pattern of the resultant * String representation. * <p> * The mask String must contain the object fieldnames that are going to be contained on the result String surrounded by * the characters '{' & '}' (e.g. <i>"{field1}"</i>). * It also can contain * <p> * For example: * <blockquote><pre> * MaskInterpreter<Author> interpreter = new MaskInterpreter<Author>( "{lastName}, {name} ({born} - {dead})" ); * System.out.println( interpreter.render( new Author( "William", "Shakespeare", 1564, 1616 ) ) ); * </pre></blockquote> * <p> * Will print on the following text: * <blockquote><pre> * Shakespeare, William (1564 - 1616) * </pre></blockquote> */ public abstract class MaskInterpreter<T> { protected List<MaskSection> sections = new ArrayList<>(); protected String mask; /** * Constructs the MaskInterpreter object using the given String as a mask * @throws NullPointerException If the mask is null * @throws IllegalArgumentException If the mask has wrong format */ public MaskInterpreter(String mask) { Assert.notNull("Mask cannot be null!", mask); this.mask = mask; if (isValid(mask)) { while (mask.contains("{") && mask.contains("}")) { int open = mask.indexOf("{"); int close = mask.indexOf("}"); String text = mask.substring(0, open); String property = mask.substring(open + 1, close); if (!text.isEmpty()) { sections.add(new MaskSectionImpl(MaskSectionType.LITERAL, text)); } sections.add(new MaskSectionImpl(MaskSectionType.PROPERTY, property)); mask = mask.substring(close + 1); } if (!mask.isEmpty()) { sections.add(new MaskSectionImpl(MaskSectionType.LITERAL, mask)); } } else { throw new IllegalArgumentException("Invalid mask!"); } } protected boolean isValid(String mask) { if (mask == null) { return false; } if (mask.isEmpty()) { return true; } int countOpeners = 0; int countClosers = 0; for (char c : mask.toCharArray()) { if (c == '{') { countOpeners++; } else if (c == '}') { countClosers++; } } return countOpeners != 0 && countOpeners == countClosers; } /** * Generates the String representation for the given Object */ public String render(T model) { if (model == null) { return ""; } if (sections.isEmpty()) { return model.toString(); } ModelInterpreter<T> interpreter = getModelInterpreter(model); String result = ""; for (MaskSection section : sections) { String value = section.getText(); if (section.getType().equals(MaskSectionType.PROPERTY)) { Object propertyValue = interpreter.getPropertyValue(section.getText()); if (propertyValue != null) { value = propertyValue.toString(); } else { value = ""; } } result += value; } return result; } protected abstract ModelInterpreter<T> getModelInterpreter(T model); /** * Returns a list containing all the mask fragments */ public List<MaskSection> getSections() { return sections; } /** * Returns the mask used to initialize the interpreter. */ public String getMask() { return mask; } private class MaskSectionImpl implements MaskSection { private MaskSectionType type; private String text; public MaskSectionImpl(MaskSectionType type, String text) { this.type = type; this.text = text; } @Override public MaskSectionType getType() { return type; } @Override public String getText() { return text; } } }