/** * Copyright (c) 2014-2017 by the respective copyright holders. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.smarthome.core.thing; import java.util.Arrays; import com.google.common.base.Joiner; /** * {@link UID} is the base class for unique identifiers within the SmartHome * framework. A UID must always start with a binding ID. * * @author Dennis Nobel - Initial contribution * @author Oliver Libutzki - Added possibility to define UIDs with variable amount of segments * @author Jochen Hiller - Bugfix 455434: added default constructor, object is now mutable */ public abstract class UID { public static final String SEGMENT_PATTERN = "[A-Za-z0-9_-]*"; public static final String SEPARATOR = ":"; private String[] segments; /** * Constructor must be public, otherwise it can not be called by subclasses from another package. */ public UID() { this.segments = null; } /** * Parses a UID for a given string. The UID must be in the format * 'bindingId:segment:segment:...'. * * @param uid * uid in form a string (must not be null) */ public UID(String uid) { this(splitToSegments(uid)); } private static String[] splitToSegments(String uid) { if (uid == null) { throw new IllegalArgumentException("Given uid must not be null."); } return uid.split(SEPARATOR); } /** * Creates a UID for list of segments. * * @param segments * segments (must not be null) */ public UID(String... segments) { if (segments == null) { throw new IllegalArgumentException("Given segments argument must not be null."); } int numberOfSegments = getMinimalNumberOfSegments(); if (segments.length < numberOfSegments) { throw new IllegalArgumentException("UID must have at least " + numberOfSegments + " segments."); } for (int i = 0; i < segments.length; i++) { String segment = segments[i]; validateSegment(segment, i, segments.length); } this.segments = segments; } /** * Specifies how many segments the UID has to have at least. * * @return */ protected abstract int getMinimalNumberOfSegments(); protected String[] getSegments() { return this.segments; } protected String getSegment(int segment) { return this.segments[segment]; } protected void validateSegment(String segment, int index, int length) { if (!segment.matches(SEGMENT_PATTERN)) { throw new IllegalArgumentException("UID segment '" + segment + "' contains invalid characters. Each segment of the UID must match the pattern [A-Za-z0-9_-]*."); } } /** * Returns the binding id. * * @return binding id */ public String getBindingId() { return segments[0]; } @Override public String toString() { return getAsString(); } public String getAsString() { return Joiner.on(SEPARATOR).join(segments); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(segments); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; UID other = (UID) obj; if (!Arrays.equals(segments, other.segments)) return false; return true; } }