Project

General

Profile

1 42181 sandro.lab
package eu.dnetlib.oai.conf;
2
3
import java.io.IOException;
4
import java.io.StringReader;
5
import java.util.ArrayList;
6
import java.util.HashMap;
7
import java.util.List;
8
import java.util.Map;
9 42184 michele.ar
10 42181 sandro.lab
import javax.xml.stream.XMLInputFactory;
11
import javax.xml.stream.XMLStreamConstants;
12
import javax.xml.stream.XMLStreamException;
13
import javax.xml.stream.XMLStreamReader;
14
import javax.xml.transform.stream.StreamSource;
15
16 42184 michele.ar
import org.apache.commons.logging.Log;
17
import org.apache.commons.logging.LogFactory;
18
19 42181 sandro.lab
import com.google.common.collect.ArrayListMultimap;
20
import com.google.common.collect.Multimap;
21 42184 michele.ar
22 42181 sandro.lab
import eu.dnetlib.oai.PublisherField;
23
import eu.dnetlib.oai.info.SetInfo;
24
import eu.dnetlib.rmi.provision.MDFInfo;
25 42184 michele.ar
import eu.dnetlib.rmi.provision.OaiPublisherRuntimeException;
26 42181 sandro.lab
27
/**
28
 * Parses an XML document representing the OAI configuration profile and creates the corresponding OAIConfiguration object.
29
 *
30
 * @author alessia
31
 */
32
public class OAIConfigurationParser {
33
34
	private static final Log log = LogFactory.getLog(OAIConfigurationParser.class); // NOPMD by marko on 11/24/08 5:02 PM
35
36
	private final ThreadLocal<XMLInputFactory> factory = new ThreadLocal<XMLInputFactory>() {
37
38
		@Override
39
		protected XMLInputFactory initialValue() {
40
			return XMLInputFactory.newInstance();
41
		}
42
	};
43
44
	public OAIConfiguration getConfiguration(final String configurationProfile) throws IOException {
45
		log.debug(configurationProfile);
46 42184 michele.ar
		final OAIConfiguration config = new OAIConfiguration();
47
		final Map<String, SetInfo> setsMap = new HashMap<>();
48
		final Map<String, MDFInfo> mdFormatsMap = new HashMap<>();
49
		final List<String> indexNames = new ArrayList<>();
50
		final List<PublisherField> fields = new ArrayList<>();
51 42181 sandro.lab
		try {
52 42184 michele.ar
			final XMLStreamReader parser = this.factory.get().createXMLStreamReader(new StreamSource(new StringReader(configurationProfile)));
53 42181 sandro.lab
			while (parser.hasNext()) {
54
				int event = parser.next();
55
				if (event == XMLStreamConstants.START_ELEMENT) {
56
					final String localName = parser.getLocalName();
57
					if (localName.equals("IDSCHEME")) {
58
						config.setIdScheme(parser.getElementText());
59
					} else if (localName.equals("IDNAMESPACE")) {
60
						config.setIdNamespace(parser.getElementText());
61
					} else if (localName.equals("OAISET")) {
62
						boolean inSet = true;
63 42184 michele.ar
						final SetInfo setInfo = new SetInfo();
64
						final String enabled = parser.getAttributeValue(null, "enabled");
65 42181 sandro.lab
						setInfo.setEnabled(Boolean.parseBoolean(enabled));
66
						while (parser.hasNext() && inSet) {
67
							event = parser.next();
68
							if (event == XMLStreamConstants.START_ELEMENT) {
69 42184 michele.ar
								final String setElementName = parser.getLocalName();
70
								final String setElementValue = parser.getElementText();
71 42181 sandro.lab
								this.handleSetInfo(setInfo, setElementName, setElementValue);
72
							}
73
							if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("OAISET")) {
74
								inSet = false;
75
								setsMap.put(setInfo.getSetSpec(), setInfo);
76
							}
77
						}
78
					} else {
79
						if (localName.equals("METADATAFORMAT")) {
80
							boolean inMetadata = true;
81 42184 michele.ar
							final MDFInfo mdfInfo = new MDFInfo();
82
							final String exportable = parser.getAttributeValue(null, "exportable");
83 42181 sandro.lab
							mdfInfo.setEnabled(Boolean.parseBoolean(exportable));
84 42184 michele.ar
							final String mdPrefix = parser.getAttributeValue(null, "metadataPrefix");
85 42181 sandro.lab
							mdfInfo.setPrefix(mdPrefix);
86
							while (parser.hasNext() && inMetadata) {
87
								event = parser.next();
88
								if (event == XMLStreamConstants.START_ELEMENT) {
89 42184 michele.ar
									final String mdfElementName = parser.getLocalName();
90 42181 sandro.lab
									if (mdfElementName.equals("SOURCE_METADATA_FORMAT")) {
91
										this.handleSourceMDF(mdfInfo, parser);
92
										config.getSourcesMDF().add(mdfInfo);
93
									} else {
94 42184 michele.ar
										final String mdfElementValue = parser.getElementText();
95 42181 sandro.lab
										this.handleMDFInfo(mdfInfo, mdfElementName, mdfElementValue);
96
									}
97
								}
98
								if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("METADATAFORMAT")) {
99
									inMetadata = false;
100
									mdFormatsMap.put(mdPrefix, mdfInfo);
101
								}
102
							}
103
						} else {
104
							// INDICES
105
							if (localName.equals("INDEX")) {
106
								boolean inIndex = true;
107 42184 michele.ar
								final PublisherField publisherField = new PublisherField();
108
								final String indexName = parser.getAttributeValue(null, "name");
109
								final String repeatable = parser.getAttributeValue(null, "repeatable");
110
								final boolean isRepeatable = Boolean.valueOf(repeatable);
111 42181 sandro.lab
								indexNames.add(indexName);
112
								publisherField.setFieldName(indexName);
113
								publisherField.setRepeatable(isRepeatable);
114
								// now let's set the SOURCES
115 42184 michele.ar
								final Multimap<String, String> fieldSources = ArrayListMultimap.create();
116 42181 sandro.lab
								while (parser.hasNext() && inIndex) {
117
									event = parser.next();
118
									if (event == XMLStreamConstants.START_ELEMENT) {
119 42184 michele.ar
										final String currentElementName = parser.getLocalName();
120 42181 sandro.lab
										this.handleIndex(fieldSources, indexName, parser, currentElementName);
121
									}
122
									if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("INDEX")) {
123
										inIndex = false;
124
									}
125
								}
126
								publisherField.setSources(fieldSources);
127
								fields.add(publisherField);
128
129
							}
130
						}
131
					}
132
				}
133
			}
134
			config.setFields(fields);
135
			config.setFieldNames(indexNames);
136
			config.setMdFormatsMap(mdFormatsMap);
137
			config.setSetsMap(setsMap);
138
			return config;
139
		} catch (final XMLStreamException e) {
140
			throw new OaiPublisherRuntimeException(e);
141
		}
142
143
	}
144
145
	/**
146
	 * Sets information about the indices.
147
	 *
148
	 * @param fieldSources
149
	 * @param indexName
150
	 * @param parser
151
	 * @param currentLocalName
152
	 */
153
	private void handleIndex(final Multimap<String, String> fieldSources, final String indexName, final XMLStreamReader parser, final String currentLocalName) {
154
		if (currentLocalName.equals("SOURCE")) {
155 42184 michele.ar
			final MDFInfo indexSource = new MDFInfo();
156 42181 sandro.lab
			this.handleSourceMDF(indexSource, parser);
157 42184 michele.ar
			final String key =
158
					indexSource.getSourceFormatName() + "-" + indexSource.getSourceFormatLayout() + "-" + indexSource.getSourceFormatInterpretation();
159 42181 sandro.lab
			fieldSources.put(key, parser.getAttributeValue(null, "path"));
160
		} else {
161
			log.warn("I do not know how to handle INDEX element with name " + currentLocalName);
162
		}
163
	}
164
165
	/**
166
	 * Sets information about the source metadata format in the given instance of MDFInfo.
167
	 *
168
	 * @param mdfInfo
169
	 * @param parser
170
	 */
171
	private void handleSourceMDF(final MDFInfo mdfInfo, final XMLStreamReader parser) {
172 42184 michele.ar
		final String interpretation = parser.getAttributeValue(null, "interpretation");
173
		final String layout = parser.getAttributeValue(null, "layout");
174
		final String name = parser.getAttributeValue(null, "name");
175 42181 sandro.lab
		mdfInfo.setSourceFormatInterpretation(interpretation);
176
		mdfInfo.setSourceFormatLayout(layout);
177
		mdfInfo.setSourceFormatName(name);
178
	}
179
180
	/**
181
	 * Sets information in the MDFInfo instance based on the element name.
182
	 *
183
	 * @param mdfInfo
184
	 * @param elementValue
185
	 * @param elementName
186
	 */
187
	private void handleMDFInfo(final MDFInfo mdfInfo, final String elementName, final String elementValue) {
188
		if (elementName.equals("NAMESPACE")) {
189
			mdfInfo.setNamespace(elementValue);
190
		} else {
191
			if (elementName.equals("SCHEMA")) {
192
				mdfInfo.setSchema(elementValue);
193
			} else {
194
				if (elementName.equals("TRANSFORMATION_RULE")) {
195
					mdfInfo.setTransformationRuleID(elementValue);
196
				} else {
197
					if (elementName.equals("BASE_QUERY")) {
198
						mdfInfo.setBaseQuery(elementValue);
199
					} else {
200
						log.warn("I do not know how to handle Metadata Format element with name " + elementName + " and value " + elementValue);
201
					}
202
				}
203
			}
204
		}
205
206
	}
207
208
	/**
209
	 * Sets information in the SetInfo instance based on the element name.
210
	 *
211
	 * @param setInfo
212
	 * @param elementName
213
	 * @param elementValue
214
	 */
215
	private void handleSetInfo(final SetInfo setInfo, final String elementName, final String elementValue) {
216
		if (elementName.equals("spec")) {
217
			setInfo.setSetSpec(elementValue);
218
		} else {
219
			if (elementName.equals("name")) {
220
				setInfo.setSetName(elementValue);
221
			} else {
222
				if (elementName.equals("description")) {
223
					setInfo.setSetDescription(elementValue);
224
				} else {
225
					if (elementName.equals("query")) {
226
						setInfo.setQuery(elementValue);
227
					} else {
228
						log.warn("I do not know how to handle Set element with name " + elementName + " and value " + elementValue);
229
					}
230
				}
231
			}
232
		}
233
	}
234
}