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.model.DDMForm;
024    import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
025    import com.liferay.portlet.dynamicdatamapping.model.UnlocalizedValue;
026    import com.liferay.portlet.dynamicdatamapping.storage.DDMFormFieldValue;
027    import com.liferay.portlet.dynamicdatamapping.storage.DDMFormValues;
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.MSOffice;
047    import org.apache.tika.metadata.Message;
048    import org.apache.tika.metadata.Metadata;
049    import org.apache.tika.metadata.Property;
050    import org.apache.tika.metadata.TIFF;
051    import org.apache.tika.metadata.TikaMetadataKeys;
052    import org.apache.tika.metadata.TikaMimeKeys;
053    import org.apache.tika.metadata.XMPDM;
054    
055    /**
056     * @author Alexander Chow
057     */
058    public abstract class BaseRawMetadataProcessor implements RawMetadataProcessor {
059    
060            @Override
061            public Map<String, Field[]> getFields() {
062                    return _fields;
063            }
064    
065            @Override
066            public Map<String, DDMFormValues> getRawMetadataMap(
067                            String extension, String mimeType, File file)
068                    throws PortalException {
069    
070                    Metadata metadata = extractMetadata(extension, mimeType, file);
071    
072                    return createDDMFormValuesMap(metadata, getFields());
073            }
074    
075            @Override
076            public Map<String, DDMFormValues> getRawMetadataMap(
077                            String extension, String mimeType, InputStream inputStream)
078                    throws PortalException {
079    
080                    Metadata metadata = extractMetadata(extension, mimeType, inputStream);
081    
082                    return createDDMFormValuesMap(metadata, getFields());
083            }
084    
085            protected DDMForm createDDMForm(Locale defaultLocale) {
086                    DDMForm ddmForm = new DDMForm();
087    
088                    ddmForm.addAvailableLocale(defaultLocale);
089                    ddmForm.setDefaultLocale(defaultLocale);
090    
091                    return ddmForm;
092            }
093    
094            protected DDMFormValues createDDMFormValues(
095                    Metadata metadata, Field[] fields) {
096    
097                    Locale defaultLocale = LocaleUtil.getDefault();
098    
099                    DDMForm ddmForm = createDDMForm(defaultLocale);
100    
101                    DDMFormValues ddmFormValues = new DDMFormValues(ddmForm);
102    
103                    ddmFormValues.addAvailableLocale(defaultLocale);
104                    ddmFormValues.setDefaultLocale(defaultLocale);
105    
106                    for (Field field : fields) {
107                            Class<?> fieldClass = field.getDeclaringClass();
108    
109                            String fieldClassName = fieldClass.getSimpleName();
110    
111                            String name = fieldClassName.concat(
112                                    StringPool.UNDERLINE).concat(field.getName());
113    
114                            String value = getMetadataValue(metadata, field);
115    
116                            if (value == null) {
117                                    continue;
118                            }
119    
120                            DDMFormField ddmFormField = createTextDDMFormField(name);
121    
122                            ddmForm.addDDMFormField(ddmFormField);
123    
124                            DDMFormFieldValue ddmFormFieldValue = new DDMFormFieldValue();
125    
126                            ddmFormFieldValue.setName(name);
127                            ddmFormFieldValue.setValue(new UnlocalizedValue(value));
128    
129                            ddmFormValues.addDDMFormFieldValue(ddmFormFieldValue);
130                    }
131    
132                    return ddmFormValues;
133            }
134    
135            protected Map<String, DDMFormValues> createDDMFormValuesMap(
136                    Metadata metadata, Map<String, Field[]> fieldsMap) {
137    
138                    Map<String, DDMFormValues> ddmFormValuesMap = new HashMap<>();
139    
140                    if (metadata == null) {
141                            return ddmFormValuesMap;
142                    }
143    
144                    for (String key : fieldsMap.keySet()) {
145                            Field[] fields = fieldsMap.get(key);
146    
147                            DDMFormValues ddmFormValues = createDDMFormValues(metadata, fields);
148    
149                            Map<String, List<DDMFormFieldValue>> ddmFormFieldsValuesMap =
150                                    ddmFormValues.getDDMFormFieldValuesMap();
151    
152                            Set<String> names = ddmFormFieldsValuesMap.keySet();
153    
154                            if (names.isEmpty()) {
155                                    continue;
156                            }
157    
158                            ddmFormValuesMap.put(key, ddmFormValues);
159                    }
160    
161                    return ddmFormValuesMap;
162            }
163    
164            protected DDMFormField createTextDDMFormField(String name) {
165                    DDMFormField ddmFormField = new DDMFormField(name, "text");
166    
167                    ddmFormField.setDataType("string");
168    
169                    return ddmFormField;
170            }
171    
172            protected abstract Metadata extractMetadata(
173                            String extension, String mimeType, File file)
174                    throws PortalException;
175    
176            protected abstract Metadata extractMetadata(
177                            String extension, String mimeType, InputStream inputStream)
178                    throws PortalException;
179    
180            protected Object getFieldValue(Metadata metadata, Field field) {
181                    Object fieldValue = null;
182    
183                    try {
184                            fieldValue = field.get(metadata);
185                    }
186                    catch (IllegalAccessException iae) {
187                            if (_log.isWarnEnabled()) {
188                                    _log.warn(
189                                            "The property " + field.getName() +
190                                                    " will not be added to the metatada set");
191                            }
192                    }
193    
194                    return fieldValue;
195            }
196    
197            protected String getMetadataValue(Metadata metadata, Field field) {
198                    Object fieldValue = getFieldValue(metadata, field);
199    
200                    if (fieldValue instanceof String) {
201                            return metadata.get((String)fieldValue);
202                    }
203    
204                    Property property = (Property)fieldValue;
205    
206                    return metadata.get(property.getName());
207            }
208    
209            private static void _addFields(Class<?> clazz, List<Field> fields) {
210                    for (Field field : clazz.getFields()) {
211                            fields.add(field);
212                    }
213            }
214    
215            private static final Log _log = LogFactoryUtil.getLog(
216                    BaseRawMetadataProcessor.class);
217    
218            private static final Map<String, Field[]> _fields = new HashMap<>();
219    
220            static {
221                    List<Field> fields = new ArrayList<>();
222    
223                    _addFields(ClimateForcast.class, fields);
224                    _addFields(CreativeCommons.class, fields);
225                    _addFields(DublinCore.class, fields);
226                    _addFields(Geographic.class, fields);
227                    _addFields(HttpHeaders.class, fields);
228                    _addFields(Message.class, fields);
229                    _addFields(MSOffice.class, fields);
230                    _addFields(TIFF.class, fields);
231                    _addFields(TikaMetadataKeys.class, fields);
232                    _addFields(TikaMimeKeys.class, fields);
233                    _addFields(XMPDM.class, fields);
234    
235                    _fields.put(
236                            TIKA_RAW_METADATA, fields.toArray(new Field[fields.size()]));
237            }
238    
239    }