/*
* #%L
* Nazgul Project: nazgul-core-algorithms-tree-model
* %%
* Copyright (C) 2010 - 2017 jGuru Europe AB
* %%
* Licensed under the jGuru Europe AB license (the "License"), based
* on Apache License, Version 2.0; you may not use this file except
* in compliance with the License.
*
* You may obtain a copy of the License at
*
* http://www.jguru.se/licenses/jguruCorporateSourceLicense-2.0.txt
*
* 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.
* #L%
*
*/
package se.jguru.nazgul.core.algorithms.tree.model.path;
import se.jguru.nazgul.core.algorithms.api.Validate;
import se.jguru.nazgul.core.algorithms.api.trees.path.Path;
import se.jguru.nazgul.core.xmlbinding.api.XmlBinder;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* AbstractPath implementation using Strings for path elements.
* <strong>Note!</strong> This implementation is immutable, implying that the append method returns a new
* instance, rather than modifying this one.
*
* @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB
*/
@Entity
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NamedQueries({
@NamedQuery(
name = "getStringPathByCompoundPath",
query = "select s from StringPath s where s.compoundPath like ?1 order by s.compoundPath")
})
@XmlType(namespace = XmlBinder.CORE_NAMESPACE)
@XmlAccessorType(XmlAccessType.FIELD)
public class StringPath extends AbstractPath<String> {
// Internal state
@Transient
@XmlTransient
private List<String> segments;
/**
* JPA/JAXB-friendly constructor.
* <strong>This is for framework use only.</strong>
*/
public StringPath() {
super();
}
/**
* Creates a StringPath with the supplied compoundPath.
*
* @param compoundPath The compoundPath of this StringPath instance.
*/
public StringPath(final String compoundPath) {
// Delegate
this(compoundPath, DEFAULT_SEGMENT_SEPARATOR);
}
/**
* Compound constructor, creating a new AbstractPath instance from the supplied data.
*
* @param compoundPath The compound path representation of this AbstractPath.
* Each segment string must be convertible to a {@code SegmentType} instance.
* @param segmentSeparator The string separating SegmentType representations from each other.
*/
public StringPath(final String compoundPath, final String segmentSeparator) {
// Delegate
super(compoundPath, segmentSeparator);
// Parse and assign internal state
segments = parseCompoundPath(compoundPath, segmentSeparator);
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("all")
public <X extends Path<String>> X append(final String aKey) {
// Wrap and return
final String newCompoundPath = getCompoundPath() + getSegmentSeparator() + aKey;
return (X) new StringPath(newCompoundPath);
}
/**
* {@inheritDoc}
*/
@Override
protected List<String> getSegments() {
// Check sanity
if (segments == null && getCompoundPath() != null) {
segments = parseCompoundPath(getCompoundPath(), getSegmentSeparator());
}
// All done.
return segments;
}
/**
* Parses the supplied compoundPath using the supplied pathSeparator, returning the resulting
* List of path segments.
*
* @param compoundPath The compound path to parse into a List of segments.
* @param pathSeparator The pathSeparator where the given compoundPath should be split.
* @return The resulting List of path segments.
*/
public static List<String> parseCompoundPath(final String compoundPath, final String pathSeparator) {
// Check sanity
Validate.notEmpty(pathSeparator, "pathSeparator");
Validate.notNull(compoundPath, "compoundPath");
// Parse and return
final List<String> toReturn = new ArrayList<String>();
final StringTokenizer tok = new StringTokenizer(compoundPath, pathSeparator, false);
if (tok.countTokens() == 0) {
toReturn.add(compoundPath);
} else {
while (tok.hasMoreTokens()) {
toReturn.add(tok.nextToken());
}
}
// All done.
return toReturn;
}
}