001package ezvcard.io.scribe; 002 003import java.util.List; 004 005import com.github.mangstadt.vinnie.io.VObjectPropertyValues; 006 007import ezvcard.VCardDataType; 008import ezvcard.VCardVersion; 009import ezvcard.io.ParseContext; 010import ezvcard.io.html.HCardElement; 011import ezvcard.io.json.JCardValue; 012import ezvcard.io.json.JsonValue; 013import ezvcard.io.text.WriteContext; 014import ezvcard.io.xml.XCardElement; 015import ezvcard.io.xml.XCardElement.XCardValue; 016import ezvcard.parameter.VCardParameters; 017import ezvcard.property.RawProperty; 018 019/* 020 Copyright (c) 2012-2023, Michael Angstadt 021 All rights reserved. 022 023 Redistribution and use in source and binary forms, with or without 024 modification, are permitted provided that the following conditions are met: 025 026 1. Redistributions of source code must retain the above copyright notice, this 027 list of conditions and the following disclaimer. 028 2. Redistributions in binary form must reproduce the above copyright notice, 029 this list of conditions and the following disclaimer in the documentation 030 and/or other materials provided with the distribution. 031 032 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 033 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 034 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 035 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 036 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 037 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 038 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 039 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 040 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 041 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 042 */ 043 044/** 045 * Marshals {@link RawProperty} properties. 046 * @author Michael Angstadt 047 */ 048/* 049 * Note concerning escaping and unescaping special characters: 050 * 051 * Values are not escaped and unescaped for the following reason: If the 052 * extended property's value is a list or structured list, then the escaping 053 * must be preserved or else escaped special characters will be lost. 054 * 055 * This is an inconvenience, considering the fact that most extended properties 056 * contain simple text values. But it is necessary in order to prevent data 057 * loss. 058 */ 059public class RawPropertyScribe extends VCardPropertyScribe<RawProperty> { 060 public RawPropertyScribe(String propertyName) { 061 super(RawProperty.class, propertyName); 062 } 063 064 @Override 065 protected VCardDataType _defaultDataType(VCardVersion version) { 066 return null; 067 } 068 069 @Override 070 protected VCardDataType _dataType(RawProperty property, VCardVersion version) { 071 return property.getDataType(); 072 } 073 074 @Override 075 protected String _writeText(RawProperty property, WriteContext context) { 076 String value = property.getValue(); 077 return (value == null) ? "" : value; 078 } 079 080 @Override 081 protected RawProperty _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) { 082 RawProperty property = new RawProperty(propertyName, value); 083 property.setDataType(dataType); 084 return property; 085 } 086 087 @Override 088 protected RawProperty _parseXml(XCardElement element, VCardParameters parameters, ParseContext context) { 089 XCardValue firstValue = element.firstValue(); 090 VCardDataType dataType = firstValue.getDataType(); 091 String value = firstValue.getValue(); 092 093 RawProperty property = new RawProperty(propertyName, value); 094 property.setDataType(dataType); 095 return property; 096 } 097 098 @Override 099 protected RawProperty _parseJson(JCardValue value, VCardDataType dataType, VCardParameters parameters, ParseContext context) { 100 String valueStr = jcardValueToString(value); 101 102 RawProperty property = new RawProperty(propertyName, valueStr); 103 property.setDataType(dataType); 104 return property; 105 } 106 107 @Override 108 protected RawProperty _parseHtml(HCardElement element, ParseContext context) { 109 String value = element.value(); 110 111 return new RawProperty(propertyName, value); 112 } 113 114 private static String jcardValueToString(JCardValue value) { 115 /* 116 * VCardPropertyScribe.jcardValueToString() cannot be used because it 117 * escapes single values. 118 */ 119 List<JsonValue> values = value.getValues(); 120 if (values.size() > 1) { 121 List<String> multi = value.asMulti(); 122 if (!multi.isEmpty()) { 123 return VObjectPropertyValues.writeList(multi); 124 } 125 } 126 127 if (!values.isEmpty() && values.get(0).getArray() != null) { 128 List<List<String>> structured = value.asStructured(); 129 if (!structured.isEmpty()) { 130 return VObjectPropertyValues.writeStructured(structured, true); 131 } 132 } 133 134 return value.asSingle(); 135 } 136}