001package ezvcard.parameter; 002 003import ezvcard.property.ClientPidMap; 004 005/* 006 Copyright (c) 2012-2023, Michael Angstadt 007 All rights reserved. 008 009 Redistribution and use in source and binary forms, with or without 010 modification, are permitted provided that the following conditions are met: 011 012 1. Redistributions of source code must retain the above copyright notice, this 013 list of conditions and the following disclaimer. 014 2. Redistributions in binary form must reproduce the above copyright notice, 015 this list of conditions and the following disclaimer in the documentation 016 and/or other materials provided with the distribution. 017 018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 019 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 021 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 022 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 024 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 025 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 027 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 028 029 The views and conclusions contained in the software and documentation are those 030 of the authors and should not be interpreted as representing official policies, 031 either expressed or implied, of the FreeBSD Project. 032 */ 033 034/** 035 * Represents a PID parameter value. A PID uniquely identifies a property. They 036 * are used when two different versions of the same vCard have to be merged 037 * together (called "synchronizing"). 038 * @author Michael Angstadt 039 * @see <a href="http://tools.ietf.org/html/rfc6350#section-5.5">RFC 6350 040 * Section 5.5</a> 041 */ 042public class Pid { 043 private final Integer localId, clientPidMapReference; 044 045 /** 046 * Creates a new PID. 047 * @param localId the local ID (cannot be null, must be positive) 048 * @param clientPidMapReference an integer that references the property's 049 * globally unique ID (optional, must be positive). It must match the first 050 * value in an existing {@link ClientPidMap} property 051 * @throws NullPointerException if local ID is null 052 */ 053 public Pid(Integer localId, Integer clientPidMapReference) { 054 if (localId == null) { 055 throw new NullPointerException("Local ID must not be null."); 056 } 057 this.localId = localId; 058 this.clientPidMapReference = clientPidMapReference; 059 } 060 061 /** 062 * Creates a new PID. 063 * @param localId the local ID (cannot be null, must be positive) 064 * @throws NullPointerException if local ID is null 065 */ 066 public Pid(Integer localId) { 067 this(localId, null); 068 } 069 070 /** 071 * Gets the local ID 072 * @return the local ID 073 */ 074 public Integer getLocalId() { 075 return localId; 076 } 077 078 /** 079 * Gets the reference to the property's globally unique ID (stored in a 080 * {@link ClientPidMap} property). 081 * @return the reference ID or null if not set 082 */ 083 public Integer getClientPidMapReference() { 084 return clientPidMapReference; 085 } 086 087 /** 088 * Parses a string into a {@link Pid} object. 089 * @param value the string value (e.g. "1.2") 090 * @return the {@link Pid} object 091 * @throws NumberFormatException if there's a problem parsing the string 092 */ 093 public static Pid valueOf(String value) { 094 int dot = value.indexOf('.'); 095 String localIdStr, clientPidMapReferenceStr; 096 if (dot < 0) { 097 localIdStr = value; 098 clientPidMapReferenceStr = null; 099 } else { 100 localIdStr = value.substring(0, dot); 101 clientPidMapReferenceStr = (dot == value.length() - 1) ? null : value.substring(dot + 1); 102 } 103 104 Integer localId = Integer.valueOf(localIdStr); 105 Integer clientPidMapReference = (clientPidMapReferenceStr == null) ? null : Integer.valueOf(clientPidMapReferenceStr); 106 return new Pid(localId, clientPidMapReference); 107 } 108 109 @Override 110 public String toString() { 111 return (clientPidMapReference == null) ? Integer.toString(localId) : localId + "." + clientPidMapReference; 112 } 113 114 @Override 115 public int hashCode() { 116 final int prime = 31; 117 int result = 1; 118 result = prime * result + ((clientPidMapReference == null) ? 0 : clientPidMapReference.hashCode()); 119 result = prime * result + localId.hashCode(); 120 return result; 121 } 122 123 @Override 124 public boolean equals(Object obj) { 125 if (this == obj) return true; 126 if (obj == null) return false; 127 if (getClass() != obj.getClass()) return false; 128 Pid other = (Pid) obj; 129 if (clientPidMapReference == null) { 130 if (other.clientPidMapReference != null) return false; 131 } else if (!clientPidMapReference.equals(other.clientPidMapReference)) return false; 132 if (!localId.equals(other.localId)) return false; 133 return true; 134 } 135}