1 /* 2 * Copyright 2020-2022 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.bremersee.xml; 18 19 import java.io.File; 20 import java.net.URL; 21 import java.util.Arrays; 22 import java.util.Collection; 23 import java.util.Collections; 24 import java.util.List; 25 import java.util.Optional; 26 import javax.xml.transform.Source; 27 import javax.xml.validation.Schema; 28 import javax.xml.validation.SchemaFactory; 29 import org.springframework.core.io.ResourceLoader; 30 import org.w3c.dom.ls.LSResourceResolver; 31 import org.xml.sax.ErrorHandler; 32 33 /** 34 * The schema builder wraps the standard {@link SchemaFactory} of Java into a builder. It also 35 * offers the ability to load schema using Spring's {@link ResourceLoader}. 36 * 37 * @author Christian Bremer 38 */ 39 public interface SchemaBuilder { 40 41 /** 42 * Creates a new schema builder. 43 * 44 * @return the schema builder 45 */ 46 static SchemaBuilder newInstance() { 47 return new SchemaBuilderImpl(); 48 } 49 50 /** 51 * Copy schema builder. 52 * 53 * @return the schema builder 54 */ 55 SchemaBuilder copy(); 56 57 /** 58 * Specifies the schema language. 59 * 60 * <p>Default is {@code javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI} 61 * ("http://www.w3.org/2001/XMLSchema"). 62 * 63 * @param schemaLanguage specifies the schema language which the used schema factory will 64 * understand 65 * @return the schema builder 66 * @see SchemaFactory#newInstance(String) 67 */ 68 SchemaBuilder withSchemaLanguage(String schemaLanguage); 69 70 /** 71 * Specifies the factory to use. 72 * 73 * @param factoryClassName the factory class name 74 * @return the schema builder 75 * @see SchemaFactory#newInstance(String, String, ClassLoader) 76 */ 77 SchemaBuilder withFactory(String factoryClassName); 78 79 /** 80 * Specifies the class loader to use. 81 * 82 * @param classLoader the class loader 83 * @return the schema builder 84 * @see SchemaFactory#newInstance(String, String, ClassLoader) 85 */ 86 SchemaBuilder withClassLoader(ClassLoader classLoader); 87 88 /** 89 * Specifies the resource loader to use. The resource loader is used to retrieve the xsd files 90 * that are specified in the schema location (see {@link #fetchSchemaSources(String...)}). 91 * 92 * <p>Default is {@link org.springframework.core.io.DefaultResourceLoader}. 93 * 94 * @param resourceLoader the resource loader 95 * @return the schema builder 96 */ 97 SchemaBuilder withResourceLoader(ResourceLoader resourceLoader); 98 99 /** 100 * Specifies the resource resolver to use. 101 * 102 * @param resourceResolver the resource resolver 103 * @return the schema builder 104 * @see SchemaFactory#setResourceResolver(LSResourceResolver) 105 */ 106 SchemaBuilder withResourceResolver(LSResourceResolver resourceResolver); 107 108 /** 109 * Specifies the error handler to use. 110 * 111 * @param errorHandler the error handler 112 * @return the schema builder 113 * @see SchemaFactory#setErrorHandler(ErrorHandler) 114 */ 115 SchemaBuilder withErrorHandler(ErrorHandler errorHandler); 116 117 /** 118 * Adds a feature to the schema factory. 119 * 120 * @param name the name 121 * @param value the value 122 * @return the schema builder 123 * @see SchemaFactory#setFeature(String, boolean) 124 */ 125 SchemaBuilder withFeature(String name, Boolean value); 126 127 /** 128 * Adds a property to the schema factory. 129 * 130 * @param name the name 131 * @param value the value 132 * @return the schema builder 133 * @see SchemaFactory#setProperty(String, Object) 134 */ 135 SchemaBuilder withProperty(String name, Object value); 136 137 /** 138 * Retrieves the schema files of the specified locations. 139 * 140 * <p>The location can have any format that is supported by the {@link ResourceLoader}. 141 * 142 * @param locations the locations 143 * @return the list 144 * @see #withResourceLoader(ResourceLoader) 145 */ 146 default List<Source> fetchSchemaSources(String... locations) { 147 return Optional.ofNullable(locations) 148 .map(a -> fetchSchemaSources(Arrays.asList(a))) 149 .orElseGet(Collections::emptyList); 150 } 151 152 /** 153 * Retrieves the schema files of the specified locations. 154 * 155 * <p>The location can have any format that is supported by the {@link ResourceLoader}. 156 * 157 * @param locations the locations 158 * @return the schema files as source list 159 * @see #withResourceLoader(ResourceLoader) 160 */ 161 List<Source> fetchSchemaSources(Collection<String> locations); 162 163 /** 164 * Retrieves the schema files of the specified locations and builds the schema. 165 * 166 * <p>The location can have any format that is supported by the {@link ResourceLoader}. 167 * 168 * @param locations the locations 169 * @return the schema 170 */ 171 default Schema buildSchema(String... locations) { 172 return Optional.ofNullable(locations) 173 .map(c -> buildSchema(fetchSchemaSources(c))) 174 .orElseGet(() -> buildSchema((Source[]) null)); 175 } 176 177 /** 178 * Builds schema. 179 * 180 * @param url the url 181 * @return the schema 182 * @see SchemaFactory#newSchema(URL) 183 */ 184 Schema buildSchema(URL url); 185 186 /** 187 * Builds schema. 188 * 189 * @param file the file 190 * @return the schema 191 * @see SchemaFactory#newSchema(File) 192 */ 193 Schema buildSchema(File file); 194 195 /** 196 * Builds schema. 197 * 198 * @param source the source 199 * @return the schema 200 * @see SchemaFactory#newSchema(Source) 201 */ 202 default Schema buildSchema(Source source) { 203 return Optional.ofNullable(source) 204 .map(s -> buildSchema(new Source[]{s})) 205 .orElseGet(() -> buildSchema((Source[]) null)); 206 } 207 208 /** 209 * Builds schema. 210 * 211 * @param sources the sources 212 * @return the schema 213 * @see SchemaFactory#newSchema(Source[]) 214 */ 215 Schema buildSchema(Source[] sources); 216 217 /** 218 * Builds schema. 219 * 220 * @param sources the sources 221 * @return the schema 222 * @see SchemaFactory#newSchema(Source[]) 223 */ 224 default Schema buildSchema(Collection<? extends Source> sources) { 225 return Optional.ofNullable(sources) 226 .map(c -> buildSchema(c.toArray(new Source[0]))) 227 .orElseGet(() -> buildSchema((Source[]) null)); 228 } 229 230 }