Project

General

Profile

1
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
import javax.xml.stream.XMLInputFactory;
10
import javax.xml.stream.XMLStreamConstants;
11
import javax.xml.stream.XMLStreamException;
12
import javax.xml.stream.XMLStreamReader;
13
import javax.xml.transform.stream.StreamSource;
14

    
15
import com.google.common.collect.ArrayListMultimap;
16
import com.google.common.collect.Multimap;
17
import eu.dnetlib.oai.PublisherField;
18
import eu.dnetlib.oai.info.SetInfo;
19
import eu.dnetlib.rmi.provision.MDFInfo;
20
import eu.dnetlib.rmi.provision.OaiPublisherRuntimeException;
21
import eu.dnetlib.utils.MetadataReference;
22
import org.apache.commons.logging.Log;
23
import org.apache.commons.logging.LogFactory;
24

    
25
/**
26
 * Parses an XML document representing the OAI configuration profile and creates the corresponding OAIConfiguration object.
27
 *
28
 * @author alessia
29
 */
30
public class OAIConfigurationParser {
31

    
32
	private static final Log log = LogFactory.getLog(OAIConfigurationParser.class); // NOPMD by marko on 11/24/08 5:02 PM
33

    
34
	private final ThreadLocal<XMLInputFactory> factory = new ThreadLocal<XMLInputFactory>() {
35

    
36
		@Override
37
		protected XMLInputFactory initialValue() {
38
			return XMLInputFactory.newInstance();
39
		}
40
	};
41

    
42
	public OAIConfiguration getConfiguration(final String configurationProfile) throws IOException {
43
		log.debug(configurationProfile);
44
		final OAIConfiguration config = new OAIConfiguration();
45
		final Map<String, SetInfo> setsMap = new HashMap<>();
46
		final Map<String, MDFInfo> mdFormatsMap = new HashMap<>();
47
		final List<String> indexNames = new ArrayList<>();
48
		final List<PublisherField> fields = new ArrayList<>();
49
		try {
50
			final XMLStreamReader parser = this.factory.get().createXMLStreamReader(new StreamSource(new StringReader(configurationProfile)));
51
			while (parser.hasNext()) {
52
				int event = parser.next();
53
				if (event == XMLStreamConstants.START_ELEMENT) {
54
					final String localName = parser.getLocalName();
55
					if (localName.equals("IDSCHEME")) {
56
						config.setIdScheme(parser.getElementText());
57
					} else if (localName.equals("IDNAMESPACE")) {
58
						config.setIdNamespace(parser.getElementText());
59
					} else if (localName.equals("OAISET")) {
60
						boolean inSet = true;
61
						final SetInfo setInfo = new SetInfo();
62
						final String enabled = parser.getAttributeValue(null, "enabled");
63
						setInfo.setEnabled(Boolean.parseBoolean(enabled));
64
						while (parser.hasNext() && inSet) {
65
							event = parser.next();
66
							if (event == XMLStreamConstants.START_ELEMENT) {
67
								final String setElementName = parser.getLocalName();
68
								final String setElementValue = parser.getElementText();
69
								this.handleSetInfo(setInfo, setElementName, setElementValue);
70
							}
71
							if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("OAISET")) {
72
								inSet = false;
73
								setsMap.put(setInfo.getSetSpec(), setInfo);
74
							}
75
						}
76
					} else {
77
						if (localName.equals("METADATAFORMAT")) {
78
							boolean inMetadata = true;
79
							final MDFInfo mdfInfo = new MDFInfo();
80
							final String exportable = parser.getAttributeValue(null, "exportable");
81
							mdfInfo.setEnabled(Boolean.parseBoolean(exportable));
82
							final String mdPrefix = parser.getAttributeValue(null, "metadataPrefix");
83
							mdfInfo.setPrefix(mdPrefix);
84
							while (parser.hasNext() && inMetadata) {
85
								event = parser.next();
86
								if (event == XMLStreamConstants.START_ELEMENT) {
87
									final String mdfElementName = parser.getLocalName();
88
									if (mdfElementName.equals("SOURCE_METADATA_FORMAT")) {
89
										this.handleSourceMDF(mdfInfo, parser);
90
										config.getSourcesMDF().add(mdfInfo.getSourceMetadataReference());
91
									} else {
92
										final String mdfElementValue = parser.getElementText();
93
										this.handleMDFInfo(mdfInfo, mdfElementName, mdfElementValue);
94
									}
95
								}
96
								if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("METADATAFORMAT")) {
97
									inMetadata = false;
98
									mdFormatsMap.put(mdPrefix, mdfInfo);
99
								}
100
							}
101
						} else {
102
							// INDICES
103
							if (localName.equals("INDEX")) {
104
								boolean inIndex = true;
105
								final PublisherField publisherField = new PublisherField();
106
								final String indexName = parser.getAttributeValue(null, "name");
107
								final String repeatable = parser.getAttributeValue(null, "repeatable");
108
								final boolean isRepeatable = Boolean.valueOf(repeatable);
109
								indexNames.add(indexName);
110
								publisherField.setFieldName(indexName);
111
								publisherField.setRepeatable(isRepeatable);
112
								// now let's set the SOURCES
113
								final Multimap<String, String> fieldSources = ArrayListMultimap.create();
114
								while (parser.hasNext() && inIndex) {
115
									event = parser.next();
116
									if (event == XMLStreamConstants.START_ELEMENT) {
117
										final String currentElementName = parser.getLocalName();
118
										this.handleIndex(fieldSources, indexName, parser, currentElementName);
119
									}
120
									if ((event == XMLStreamConstants.END_ELEMENT) && parser.getLocalName().equals("INDEX")) {
121
										inIndex = false;
122
									}
123
								}
124
								publisherField.setSources(fieldSources);
125
								fields.add(publisherField);
126

    
127
							}
128
						}
129
					}
130
				}
131
			}
132
			config.setFields(fields);
133
			config.setFieldNames(indexNames);
134
			config.setMdFormatsMap(mdFormatsMap);
135
			config.setSetsMap(setsMap);
136
			return config;
137
		} catch (final XMLStreamException e) {
138
			throw new OaiPublisherRuntimeException(e);
139
		}
140

    
141
	}
142

    
143
	/**
144
	 * Sets information about the indices.
145
	 *
146
	 * @param fieldSources
147
	 * @param indexName
148
	 * @param parser
149
	 * @param currentLocalName
150
	 */
151
	private void handleIndex(final Multimap<String, String> fieldSources, final String indexName, final XMLStreamReader parser, final String currentLocalName) {
152
		if (currentLocalName.equals("SOURCE")) {
153
			final MDFInfo indexSource = new MDFInfo();
154
			this.handleSourceMDF(indexSource, parser);
155
			final String key =
156
					indexSource.getSourceFormat() + "-" + indexSource.getSourceLayout() + "-" + indexSource.getSourceInterpretation();
157
			fieldSources.put(key, parser.getAttributeValue(null, "path"));
158
		} else {
159
			log.warn("I do not know how to handle INDEX element with name " + currentLocalName);
160
		}
161
	}
162

    
163
	/**
164
	 * Sets information about the source metadata format in the given instance of MDFInfo.
165
	 *
166
	 * @param mdfInfo
167
	 * @param parser
168
	 */
169
	private void handleSourceMDF(final MDFInfo mdfInfo, final XMLStreamReader parser) {
170
		final String interpretation = parser.getAttributeValue(null, "interpretation");
171
		final String layout = parser.getAttributeValue(null, "layout");
172
		final String name = parser.getAttributeValue(null, "name");
173
		MetadataReference mdref = new MetadataReference(name, layout, interpretation);
174
		mdfInfo.setSourceMetadataReference(mdref);
175
	}
176

    
177
	/**
178
	 * Sets information in the MDFInfo instance based on the element name.
179
	 *
180
	 * @param mdfInfo
181
	 * @param elementValue
182
	 * @param elementName
183
	 */
184
	private void handleMDFInfo(final MDFInfo mdfInfo, final String elementName, final String elementValue) {
185
		if (elementName.equals("NAMESPACE")) {
186
			mdfInfo.setNamespace(elementValue);
187
		} else {
188
			if (elementName.equals("SCHEMA")) {
189
				mdfInfo.setSchema(elementValue);
190
			} else {
191
				if (elementName.equals("TRANSFORMATION_RULE")) {
192
					mdfInfo.setTransformationRuleID(elementValue);
193
				} else {
194
					if (elementName.equals("BASE_QUERY")) {
195
						mdfInfo.setBaseQuery(elementValue);
196
					} else {
197
						log.warn("I do not know how to handle Metadata Format element with name " + elementName + " and value " + elementValue);
198
					}
199
				}
200
			}
201
		}
202

    
203
	}
204

    
205
	/**
206
	 * Sets information in the SetInfo instance based on the element name.
207
	 *
208
	 * @param setInfo
209
	 * @param elementName
210
	 * @param elementValue
211
	 */
212
	private void handleSetInfo(final SetInfo setInfo, final String elementName, final String elementValue) {
213
		if (elementName.equals("spec")) {
214
			setInfo.setSetSpec(elementValue);
215
		} else {
216
			if (elementName.equals("name")) {
217
				setInfo.setSetName(elementValue);
218
			} else {
219
				if (elementName.equals("description")) {
220
					setInfo.setSetDescription(elementValue);
221
				} else {
222
					if (elementName.equals("query")) {
223
						setInfo.setQuery(elementValue);
224
					} else {
225
						log.warn("I do not know how to handle Set element with name " + elementName + " and value " + elementValue);
226
					}
227
				}
228
			}
229
		}
230
	}
231
}
(3-3/6)