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 }