FormatPattern.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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.apache.calcite.util.format.postgresql.format;
import org.apache.calcite.util.format.postgresql.PatternModifier;
import org.apache.calcite.util.format.postgresql.format.compiled.CompiledPattern;
import com.google.common.collect.ImmutableSet;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Set;
/**
* A single component of a date/time format pattern such as YYYY or MI. Each
* component may have some flags applied. If the flags are not used by a component,
* then they are ignored.
*/
public abstract class FormatPattern {
protected final String pattern;
/**
* Base class constructor that stores the pattern.
*
* @param pattern the date/time component taht this FormatPattern represents
*/
protected FormatPattern(String pattern) {
this.pattern = pattern;
}
/**
* Creates the compiled version of the parsed date/time component along with
* any flags that it had. It is expected that the formatString has the date/time
* component (with its flags) at the position indicated in formatParsePosition.
*
* @param formatString the full date/time format string
* @param formatParsePosition starting position in formatString with this
* pattern is located
* @return the compiled version of the parsed date/time component
* @throws ParseException If the date/time format component was not found
*/
public CompiledPattern compilePattern(String formatString,
ParsePosition formatParsePosition) throws ParseException {
String formatTrimmed = formatString.substring(formatParsePosition.getIndex());
int charsConsumed = 0;
final ImmutableSet.Builder<PatternModifier> modifiers = ImmutableSet.builder();
// Find the prefix modifiers
boolean modifierFound = true;
while (modifierFound) {
modifierFound = false;
for (PatternModifier modifier : PatternModifier.values()) {
if (modifier.isPrefix() && formatTrimmed.startsWith(modifier.getModifierString())) {
modifiers.add(modifier);
formatTrimmed = formatTrimmed.substring(modifier.getModifierString().length());
charsConsumed += modifier.getModifierString().length();
modifierFound = true;
break;
}
}
}
if (formatTrimmed.startsWith(pattern)) {
charsConsumed += pattern.length();
formatTrimmed = formatString.substring(formatParsePosition.getIndex() + charsConsumed);
// Find the suffix modifiers
modifierFound = true;
while (modifierFound) {
modifierFound = false;
for (PatternModifier modifier : PatternModifier.values()) {
if (!modifier.isPrefix() && formatTrimmed.startsWith(modifier.getModifierString())) {
modifiers.add(modifier);
formatTrimmed = formatTrimmed.substring(modifier.getModifierString().length());
modifierFound = true;
break;
}
}
}
return buildCompiledPattern(modifiers.build());
}
throw new ParseException("Pattern not found", formatParsePosition.getIndex());
}
/**
* Creates a new instance of the compiled version of this date/time component.
*
* @param modifiers the set of flags that were parsed
* @return a new instance of the compiled version of this date/time component
*/
protected abstract CompiledPattern buildCompiledPattern(Set<PatternModifier> modifiers);
public String getPattern() {
return pattern;
}
}