001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.metadata;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.metadata.RawMetadataProcessor;
021    import com.liferay.portal.kernel.util.LocaleUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portlet.dynamicdatamapping.DDMForm;
024    import com.liferay.portlet.dynamicdatamapping.DDMFormField;
025    import com.liferay.portlet.dynamicdatamapping.DDMFormFieldValue;
026    import com.liferay.portlet.dynamicdatamapping.DDMFormValues;
027    import com.liferay.portlet.dynamicdatamapping.UnlocalizedValue;
028    
029    import java.io.File;
030    import java.io.InputStream;
031    
032    import java.lang.reflect.Field;
033    
034    import java.util.ArrayList;
035    import java.util.HashMap;
036    import java.util.List;
037    import java.util.Locale;
038    import java.util.Map;
039    import java.util.Set;
040    
041    import org.apache.tika.metadata.ClimateForcast;
042    import org.apache.tika.metadata.CreativeCommons;
043    import org.apache.tika.metadata.DublinCore;
044    import org.apache.tika.metadata.Geographic;
045    import org.apache.tika.metadata.HttpHeaders;
046    import org.apache.tika.metadata.Message;
047    import org.apache.tika.metadata.Metadata;
048    import org.apache.tika.metadata.Office;
049    import org.apache.tika.metadata.OfficeOpenXMLCore;
050    import org.apache.tika.metadata.Property;
051    import org.apache.tika.metadata.TIFF;
052    import org.apache.tika.metadata.TikaMetadataKeys;
053    import org.apache.tika.metadata.TikaMimeKeys;
054    import org.apache.tika.metadata.XMPDM;
055    
056    /**
057     * @author Alexander Chow
058     */
059    public abstract class BaseRawMetadataProcessor implements RawMetadataProcessor {
060    
061            @Override
062            public Map<String, Field[]> getFields() {
063                    return _fields;
064            }
065    
066            @Override
067            public Map<String, DDMFormValues> getRawMetadataMap(
068                            String extension, String mimeType, File file)
069                    throws PortalException {
070    
071                    Metadata metadata = extractMetadata(extension, mimeType, file);
072    
073                    return createDDMFormValuesMap(metadata, getFields());
074            }
075    
076            @Override
077            public Map<String, DDMFormValues> getRawMetadataMap(
078                            String extension, String mimeType, InputStream inputStream)
079                    throws PortalException {
080    
081                    Metadata metadata = extractMetadata(extension, mimeType, inputStream);
082    
083                    return createDDMFormValuesMap(metadata, getFields());
084            }
085    
086            protected DDMForm createDDMForm(Locale defaultLocale) {
087                    DDMForm ddmForm = new DDMForm();
088    
089                    ddmForm.addAvailableLocale(defaultLocale);
090                    ddmForm.setDefaultLocale(defaultLocale);
091    
092                    return ddmForm;
093            }
094    
095            protected DDMFormValues createDDMFormValues(
096                    Metadata metadata, Field[] fields) {
097    
098                    Locale defaultLocale = LocaleUtil.getDefault();
099    
100                    DDMForm ddmForm = createDDMForm(defaultLocale);
101    
102                    DDMFormValues ddmFormValues = new DDMFormValues(ddmForm);
103    
104                    ddmFormValues.addAvailableLocale(defaultLocale);
105                    ddmFormValues.setDefaultLocale(defaultLocale);
106    
107                    for (Field field : fields) {
108                            Class<?> fieldClass = field.getDeclaringClass();
109    
110                            String fieldClassName = fieldClass.getSimpleName();
111    
112                            String name = fieldClassName.concat(
113                                    StringPool.UNDERLINE).concat(field.getName());
114    
115                            String value = getMetadataValue(metadata, field);
116    
117                            if (value == null) {
118                                    continue;
119                            }
120    
121                            DDMFormField ddmFormField = createTextDDMFormField(name);
122    
123                            ddmForm.addDDMFormField(ddmFormField);
124    
125                            DDMFormFieldValue ddmFormFieldValue = new DDMFormFieldValue();
126    
127                            ddmFormFieldValue.setName(name);
128                            ddmFormFieldValue.setValue(new UnlocalizedValue(value));
129    
130                            ddmFormValues.addDDMFormFieldValue(ddmFormFieldValue);
131                    }
132    
133                    return ddmFormValues;
134            }
135    
136            protected Map<String, DDMFormValues> createDDMFormValuesMap(
137                    Metadata metadata, Map<String, Field[]> fieldsMap) {
138    
139                    Map<String, DDMFormValues> ddmFormValuesMap = new HashMap<>();
140    
141                    if (metadata == null) {
142                            return ddmFormValuesMap;
143                    }
144    
145                    for (String key : fieldsMap.keySet()) {
146                            Field[] fields = fieldsMap.get(key);
147    
148                            DDMFormValues ddmFormValues = createDDMFormValues(metadata, fields);
149    
150                            Map<String, List<DDMFormFieldValue>> ddmFormFieldsValuesMap =
151                                    ddmFormValues.getDDMFormFieldValuesMap();
152    
153                            Set<String> names = ddmFormFieldsValuesMap.keySet();
154    
155                            if (names.isEmpty()) {
156                                    continue;
157                            }
158    
159                            ddmFormValuesMap.put(key, ddmFormValues);
160                    }
161    
162                    return ddmFormValuesMap;
163            }
164    
165            protected DDMFormField createTextDDMFormField(String name) {
166                    DDMFormField ddmFormField = new DDMFormField(name, "text");
167    
168                    ddmFormField.setDataType("string");
169    
170                    return ddmFormField;
171            }
172    
173            protected abstract Metadata extractMetadata(
174                            String extension, String mimeType, File file)
175                    throws PortalException;
176    
177            protected abstract Metadata extractMetadata(
178                            String extension, String mimeType, InputStream inputStream)
179                    throws PortalException;
180    
181            protected Object getFieldValue(Metadata metadata, Field field) {
182                    Object fieldValue = null;
183    
184                    try {
185                            fieldValue = field.get(metadata);
186                    }
187                    catch (IllegalAccessException iae) {
188                            if (_log.isWarnEnabled()) {
189                                    _log.warn(
190                                            "The property " + field.getName() +
191                                                    " will not be added to the metatada set");
192                            }
193                    }
194    
195                    return fieldValue;
196            }
197    
198            protected String getMetadataValue(Metadata metadata, Field field) {
199                    Object fieldValue = getFieldValue(metadata, field);
200    
201                    if (fieldValue instanceof String) {
202                            return metadata.get((String)fieldValue);
203                    }
204    
205                    Property property = (Property)fieldValue;
206    
207                    return metadata.get(property.getName());
208            }
209    
210            private static void _addFields(Class<?> clazz, List<Field> fields) {
211                    for (Field field : clazz.getFields()) {
212                            fields.add(field);
213                    }
214            }
215    
216            private static final Log _log = LogFactoryUtil.getLog(
217                    BaseRawMetadataProcessor.class);
218    
219            private static final Map<String, Field[]> _fields = new HashMap<>();
220    
221            static {
222                    List<Field> fields = new ArrayList<>();
223    
224                    _addFields(ClimateForcast.class, fields);
225                    _addFields(CreativeCommons.class, fields);
226                    _addFields(DublinCore.class, fields);
227                    _addFields(Geographic.class, fields);
228                    _addFields(HttpHeaders.class, fields);
229                    _addFields(Message.class, fields);
230                    _addFields(Office.class, fields);
231                    _addFields(OfficeOpenXMLCore.class, fields);
232                    _addFields(TIFF.class, fields);
233                    _addFields(TikaMetadataKeys.class, fields);
234                    _addFields(TikaMimeKeys.class, fields);
235                    _addFields(XMPDM.class, fields);
236    
237                    _fields.put(
238                            TIKA_RAW_METADATA, fields.toArray(new Field[fields.size()]));
239            }
240    
241    }