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.oai.publisher.OaiPublisherRuntimeException;
20
import eu.dnetlib.rmi.provision.MDFInfo;
21
import org.apache.commons.logging.Log;
22
import org.apache.commons.logging.LogFactory;
23

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

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

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

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

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

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

    
140
	}
141

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

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

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

    
202
	}
203

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