/******************************************************************************* * PSHDL is a library and (trans-)compiler for PSHDL input. It generates * output suitable for implementation or simulation of it. * * Copyright (C) 2013 Karsten Becker (feedback (at) pshdl (dot) org) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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, see <http://www.gnu.org/licenses/>. * * This License does not grant permission to use the trade names, trademarks, * service marks, or product names of the Licensor, except as required for * reasonable and customary use in describing the origin of the Work. * * Contributors: * Karsten Becker - initial API and implementation ******************************************************************************/ package org.pshdl.model.utils; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import javax.annotation.Nonnull; public class HDLQualifiedName implements Comparable<HDLQualifiedName> { public static final String INVALID = "!INVALID!"; public static final char LOCAL_TYPE_SEP = '@'; public static final HDLQualifiedName EMPTY = new HDLQualifiedName(new String[0]); private final String[] qfn; public final int length; private static final boolean validate = false; public HDLQualifiedName(String[] qfn) { this.qfn = qfn; if (qfn == null) throw new IllegalArgumentException("Segments may not be null"); this.length = qfn.length; if (validate) { for (final String string : qfn) { if (string == null) throw new IllegalArgumentException("Segments may not be null"); if (string.contains(".")) throw new IllegalArgumentException("Segments may not contain dots"); if (string.isEmpty()) throw new IllegalArgumentException("Segments may not be empty"); } } } public HDLQualifiedName(String qfn) { this(qfn == null ? new String[0] : qfn.split("\\.")); } @Nonnull public String[] getQfn() { return qfn; } @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + Arrays.hashCode(qfn); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final HDLQualifiedName other = (HDLQualifiedName) obj; if (!Arrays.equals(qfn, other.qfn)) return false; return true; } @Override public String toString() { final char c = '.'; return toString(c); } @Nonnull public String getSegment(int i) { return qfn[i]; } @Nonnull public static HDLQualifiedName create(String... segments) { return new HDLQualifiedName(segments); } @Nonnull public HDLQualifiedName skipLast(int i) { final int len = qfn.length - i; if (len < 0) throw new IllegalArgumentException("Can not skip last:" + i + " of " + this); final String[] newQfn = new String[len]; System.arraycopy(qfn, 0, newQfn, 0, len); return new HDLQualifiedName(newQfn); } @Nonnull public String getLastSegment() { return qfn[qfn.length - 1]; } /** * Prints the Qualified name using c as separator * * @param c * the separator * @return */ @Nonnull public String toString(char c) { boolean first = true; final StringBuilder sb = new StringBuilder(); for (final String part : qfn) { if (!first) { sb.append(c); } sb.append(part); first = false; } return sb.toString(); } /** * Generates a new HDLQualifiedName with the name appended * * @param name * the segment to append * @return a new HDLQualifiedName instance */ @Nonnull public HDLQualifiedName append(String name) { final int len = length + 1; final String[] newQfn = new String[len]; System.arraycopy(qfn, 0, newQfn, 0, length); newQfn[length] = name; return new HDLQualifiedName(newQfn); } @Nonnull public HDLQualifiedName skipFirst(int i) { final int len = qfn.length - i; if (len < 0) throw new IllegalArgumentException("Can not skip last:" + i + " of " + this); final String[] newQfn = new String[len]; System.arraycopy(qfn, i, newQfn, 0, len); return new HDLQualifiedName(newQfn); } @Nonnull public static HDLQualifiedName create(List<String> segments) { return new HDLQualifiedName(segments.toArray(new String[segments.size()])); } @Nonnull public HDLQualifiedName toSegment(int i) { final int len = i; if ((len < 0) || (len >= qfn.length)) throw new IllegalArgumentException("Can not skip last:" + i + " of " + this); final String[] newQfn = new String[len]; System.arraycopy(qfn, 0, newQfn, 0, len); return new HDLQualifiedName(newQfn); } @Nonnull public HDLQualifiedName append(HDLQualifiedName hdlQualifiedName) { final LinkedList<String> ll = new LinkedList<String>(); ll.addAll(Arrays.asList(this.qfn)); ll.addAll(Arrays.asList(hdlQualifiedName.qfn)); return HDLQualifiedName.create(ll); } @Nonnull public HDLQualifiedName getTypePart() { final List<String> res = new LinkedList<String>(); for (final String segment : qfn) if (segment.charAt(0) != LOCAL_TYPE_SEP) { res.add(segment); } else { break; } return create(res); } @Nonnull public HDLQualifiedName getLocalPart() { final List<String> res = new LinkedList<String>(); if (qfn.length <= 1) return this; for (final String segment : qfn) if (segment.charAt(0) == LOCAL_TYPE_SEP) { res.add(segment); } res.add(getLastSegment()); return create(res); } @Override public int compareTo(HDLQualifiedName arg0) { return toString().compareTo(arg0.toString()); } public static HDLQualifiedName invalid(String string) { return new HDLQualifiedName(INVALID + "." + string); } }