001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.databind.io; 007 008import java.io.File; 009import java.io.IOException; 010import java.io.InputStream; 011import java.io.InputStreamReader; 012import java.io.Reader; 013import java.net.URI; 014import java.net.URISyntaxException; 015import java.net.URL; 016import java.nio.charset.StandardCharsets; 017import java.nio.file.Files; 018import java.nio.file.Path; 019 020import dev.metaschema.core.configuration.IConfiguration; 021import dev.metaschema.core.configuration.IMutableConfiguration; 022import dev.metaschema.core.metapath.item.node.INodeItem; 023import dev.metaschema.core.model.IBoundObject; 024import dev.metaschema.core.model.constraint.IConstraintValidationHandler; 025import dev.metaschema.core.util.ObjectUtils; 026import edu.umd.cs.findbugs.annotations.NonNull; 027 028/** 029 * Implementations of this interface are able to read structured data into a 030 * bound object instance of the parameterized type. 031 * 032 * @param <CLASS> 033 * the Java type into which data can be read 034 */ 035public interface IDeserializer<CLASS extends IBoundObject> extends IMutableConfiguration<DeserializationFeature<?>> { 036 037 @Override 038 IDeserializer<CLASS> enableFeature(DeserializationFeature<?> feature); 039 040 @Override 041 IDeserializer<CLASS> disableFeature(DeserializationFeature<?> feature); 042 043 @Override 044 IDeserializer<CLASS> applyConfiguration(IConfiguration<DeserializationFeature<?>> other); 045 046 @Override 047 IDeserializer<CLASS> set(DeserializationFeature<?> feature, Object value); 048 049 /** 050 * Determine if the serializer is performing validation. 051 * 052 * @return {@code true} if the serializer is performing content validation, or 053 * {@code false} otherwise 054 */ 055 default boolean isValidating() { 056 return isFeatureEnabled(DeserializationFeature.DESERIALIZE_VALIDATE_CONSTRAINTS); 057 } 058 059 /** 060 * Get the constraint validation handler configured for this deserializer, which 061 * will be used to validate loaded data. 062 * 063 * @return the validation handler 064 */ 065 @NonNull 066 IConstraintValidationHandler getConstraintValidationHandler(); 067 068 /** 069 * Set the constraint violation handler for constraint validation. 070 * 071 * @param handler 072 * the handler to use 073 */ 074 void setConstraintValidationHandler(@NonNull IConstraintValidationHandler handler); 075 076 /** 077 * Read data from the {@link InputStream} into a bound class instance. 078 * 079 * @param is 080 * the input stream to read from 081 * @param documentUri 082 * the URI of the document to read from 083 * @return the instance data 084 * @throws IOException 085 * if an error occurred while reading data from the stream 086 */ 087 @NonNull 088 default CLASS deserialize(@NonNull InputStream is, @NonNull URI documentUri) throws IOException { 089 return deserialize(new InputStreamReader(is, StandardCharsets.UTF_8), documentUri); 090 } 091 092 /** 093 * Read data from the {@link Path} into a bound class instance. 094 * 095 * @param path 096 * the file to read from 097 * @return the instance data 098 * @throws IOException 099 * if an error occurred while writing data to the file indicated by 100 * the {@code path} parameter 101 */ 102 @NonNull 103 default CLASS deserialize(@NonNull Path path) throws IOException { 104 try (Reader reader = ObjectUtils.notNull(Files.newBufferedReader(path, StandardCharsets.UTF_8))) { 105 return deserialize(reader, ObjectUtils.notNull(path.toUri())); 106 } 107 } 108 109 /** 110 * Read data from the {@link File} into a bound class instance. 111 * 112 * @param file 113 * the file to read from 114 * @return the instance data 115 * @throws IOException 116 * if an error occurred while reading data from the stream 117 */ 118 @NonNull 119 default CLASS deserialize(@NonNull File file) throws IOException { 120 return deserialize(ObjectUtils.notNull(file.toPath())); 121 } 122 123 /** 124 * Read data from the remote resource into a bound class instance. 125 * 126 * 127 * @param url 128 * the remote resource to read from 129 * @return the instance data 130 * @throws IOException 131 * if an error occurred while reading data from the stream 132 * @throws URISyntaxException 133 * if the provided URL is not formatted strictly according to to 134 * RFC2396 and cannot be converted to a URI. 135 */ 136 @NonNull 137 default CLASS deserialize(@NonNull URL url) throws IOException, URISyntaxException { 138 try (InputStream in = ObjectUtils.notNull(url.openStream())) { 139 return deserialize(in, ObjectUtils.notNull(url.toURI())); 140 } 141 } 142 143 /** 144 * Read data from the {@link Reader} into a bound class instance. 145 * 146 * 147 * @param reader 148 * the reader to read from 149 * @param documentUri 150 * the URI of the document to read from 151 * @return the instance data 152 * @throws IOException 153 * if an error occurred while reading data from the stream 154 */ 155 @NonNull 156 default CLASS deserialize(@NonNull Reader reader, @NonNull URI documentUri) throws IOException { 157 return deserializeToValue(reader, documentUri); 158 } 159 160 /** 161 * Read data from the {@link Reader} into a node item instance. 162 * 163 * @param is 164 * the input stream to read from 165 * @param documentUri 166 * the URI of the document to read from 167 * @return a new node item 168 * @throws IOException 169 * if an error occurred while reading data from the stream 170 */ 171 @NonNull 172 default INodeItem deserializeToNodeItem(@NonNull InputStream is, @NonNull URI documentUri) 173 throws IOException { 174 return deserializeToNodeItem(new InputStreamReader(is, StandardCharsets.UTF_8), documentUri); 175 } 176 177 /** 178 * Read data from the {@link Reader} into a node item instance. 179 * 180 * @param reader 181 * the reader to read from 182 * @param documentUri 183 * the URI of the document to read from 184 * @return a new node item 185 * @throws IOException 186 * if an error occurred while reading data from the stream 187 */ 188 @NonNull 189 INodeItem deserializeToNodeItem(@NonNull Reader reader, @NonNull URI documentUri) throws IOException; 190 191 /** 192 * Read data from the {@link Reader} into a node item instance. 193 * 194 * @param reader 195 * the reader to read from 196 * @param documentUri 197 * the URI of the document to read from 198 * @return a new node item 199 * @throws IOException 200 * if an error occurred while reading data from the stream 201 */ 202 @NonNull 203 CLASS deserializeToValue(@NonNull Reader reader, @NonNull URI documentUri) throws IOException; 204}