001package ezvcard.property; 002 003import java.util.LinkedHashMap; 004import java.util.List; 005import java.util.Map; 006 007import com.github.mangstadt.vinnie.SyntaxStyle; 008import com.github.mangstadt.vinnie.validate.AllowedCharacters; 009import com.github.mangstadt.vinnie.validate.VObjectValidator; 010 011import ezvcard.VCard; 012import ezvcard.VCardDataType; 013import ezvcard.VCardVersion; 014import ezvcard.ValidationWarning; 015 016/* 017 Copyright (c) 2012-2023, Michael Angstadt 018 All rights reserved. 019 020 Redistribution and use in source and binary forms, with or without 021 modification, are permitted provided that the following conditions are met: 022 023 1. Redistributions of source code must retain the above copyright notice, this 024 list of conditions and the following disclaimer. 025 2. Redistributions in binary form must reproduce the above copyright notice, 026 this list of conditions and the following disclaimer in the documentation 027 and/or other materials provided with the distribution. 028 029 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 030 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 031 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 032 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 033 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 034 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 035 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 036 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 038 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 039 040 The views and conclusions contained in the software and documentation are those 041 of the authors and should not be interpreted as representing official policies, 042 either expressed or implied, of the FreeBSD Project. 043 */ 044 045/** 046 * Holds the property value as-is. No escaping or unescaping is done on the 047 * value. 048 * @author Michael Angstadt 049 */ 050public class RawProperty extends TextProperty { 051 private String propertyName; 052 private VCardDataType dataType; 053 054 /** 055 * Creates a raw property. 056 * @param propertyName the property name (e.g. "X-GENDER") 057 * @param value the property value 058 */ 059 public RawProperty(String propertyName, String value) { 060 this(propertyName, value, null); 061 } 062 063 /** 064 * Creates a raw property. 065 * @param propertyName the property name (e.g. "X-GENDER") 066 * @param value the property value 067 * @param dataType the value's data type 068 */ 069 public RawProperty(String propertyName, String value, VCardDataType dataType) { 070 super(value); 071 this.propertyName = propertyName; 072 this.dataType = dataType; 073 } 074 075 /** 076 * Copy constructor. 077 * @param original the property to make a copy of 078 */ 079 public RawProperty(RawProperty original) { 080 super(original); 081 propertyName = original.propertyName; 082 dataType = original.dataType; 083 } 084 085 /** 086 * Gets the name of the property. 087 * @return the property name 088 */ 089 public String getPropertyName() { 090 return propertyName; 091 } 092 093 /** 094 * Sets the name of the property. 095 * @param propertyName the property name 096 */ 097 public void setPropertyName(String propertyName) { 098 this.propertyName = propertyName; 099 } 100 101 /** 102 * Gets the data type of the property's value. 103 * @return the data type or null if unknown 104 */ 105 public VCardDataType getDataType() { 106 return dataType; 107 } 108 109 /** 110 * Sets the data type of the property's value. 111 * @param dataType the data type or null if unknown 112 */ 113 public void setDataType(VCardDataType dataType) { 114 this.dataType = dataType; 115 } 116 117 @Override 118 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 119 SyntaxStyle syntax = version.getSyntaxStyle(); 120 AllowedCharacters allowed = VObjectValidator.allowedCharactersParameterName(syntax, true); 121 if (!allowed.check(propertyName)) { 122 if (syntax == SyntaxStyle.OLD) { 123 AllowedCharacters notAllowed = allowed.flip(); 124 warnings.add(new ValidationWarning(33, propertyName, notAllowed.toString(true))); 125 } else { 126 warnings.add(new ValidationWarning(24, propertyName)); 127 } 128 } 129 } 130 131 @Override 132 protected Map<String, Object> toStringValues() { 133 Map<String, Object> values = new LinkedHashMap<>(); 134 values.put("propertyName", propertyName); 135 values.put("dataType", dataType); 136 values.put("value", value); 137 return values; 138 } 139 140 @Override 141 public RawProperty copy() { 142 return new RawProperty(this); 143 } 144 145 @Override 146 public int hashCode() { 147 final int prime = 31; 148 int result = super.hashCode(); 149 result = prime * result + ((dataType == null) ? 0 : dataType.hashCode()); 150 result = prime * result + ((propertyName == null) ? 0 : propertyName.toLowerCase().hashCode()); 151 return result; 152 } 153 154 @Override 155 public boolean equals(Object obj) { 156 if (this == obj) return true; 157 if (!super.equals(obj)) return false; 158 RawProperty other = (RawProperty) obj; 159 if (dataType == null) { 160 if (other.dataType != null) return false; 161 } else if (!dataType.equals(other.dataType)) return false; 162 if (propertyName == null) { 163 if (other.propertyName != null) return false; 164 } else if (!propertyName.equalsIgnoreCase(other.propertyName)) return false; 165 return true; 166 } 167}