org.apache.openmeetings.db.dao.label.LabelDao.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openmeetings.db.dao.label.LabelDao.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.db.dao.label;

import static org.apache.openmeetings.db.util.ApplicationHelper.ensureApplication;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.openmeetings.db.dao.IDataProviderDao;
import org.apache.openmeetings.db.entity.label.StringLabel;
import org.apache.openmeetings.util.OmFileHelper;
import org.apache.openmeetings.util.XmlExport;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.util.string.Strings;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * 
 * CRUD operations for {@link StringLabel}
 * 
 * @author solomax, swagner
 * 
 */
public class LabelDao implements IDataProviderDao<StringLabel> {
    private static final Logger log = Red5LoggerFactory.getLogger(LabelDao.class, webAppRootKey);
    private static final String ENTRY_ELEMENT = "entry";
    private static final String KEY_ATTR = "key";
    public static final String APP_RESOURCES_EN = "Application.properties.xml";
    public static final String APP_RESOURCES = "Application_%s.properties.xml";
    public static final LinkedHashMap<Long, Locale> languages = new LinkedHashMap<Long, Locale>(); //TODO hide it and return unmodifiable map
    public static final ConcurrentHashMap<Locale, List<StringLabel>> labelCache = new ConcurrentHashMap<Locale, List<StringLabel>>();
    public static final Set<String> keys = new HashSet<String>();
    private static Class<?> APP = null;

    public List<Map<String, Object>> getStrings(Long language_id, int start, int count) {
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < count; ++i) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", start + i);
            map.put("value", getString(start + i, language_id));
            result.add(map);
        }
        return result;
    }

    private static void storeLanguages() throws Exception {
        Document d = XmlExport.createDocument();
        Element r = XmlExport.createRoot(d, "language");
        for (Map.Entry<Long, Locale> e : languages.entrySet()) {
            r.addElement("lang").addAttribute("id", "" + e.getKey()).addAttribute("code",
                    e.getValue().toLanguageTag());
        }
        XmlExport.toXml(getLangFile(), d);
    }

    public static void add(Locale l) throws Exception {
        long id = 0L;
        for (Map.Entry<Long, Locale> e : languages.entrySet()) {
            id = e.getKey();
        }
        languages.put(id + 1, l);
        storeLanguages();
        labelCache.put(l, new ArrayList<StringLabel>());
    }

    public String getString(long fieldValuesId, long langId) {
        return ensureApplication(langId).getOmString(fieldValuesId, langId);
    }

    public String getString(String key, long langId) {
        return ensureApplication(langId).getOmString(key, langId);
    }

    private static File getLangFile() {
        return new File(OmFileHelper.getLanguagesDir(), OmFileHelper.nameOfLanguageFile);
    }

    public static synchronized Class<?> getAppClass() throws ClassNotFoundException {
        if (APP == null) {
            //FIXME HACK to resolve package dependencies
            APP = Class.forName("org.apache.openmeetings.web.app.Application");
        }
        return APP;
    }

    public static void initLanguageMap() {
        SAXReader reader = new SAXReader();
        try {
            getAppClass();
            Document document = reader.read(getLangFile());
            Element root = document.getRootElement();
            languages.clear();
            for (@SuppressWarnings("unchecked")
            Iterator<Element> it = root.elementIterator("lang"); it.hasNext();) {
                Element item = it.next();
                Long id = Long.valueOf(item.attributeValue("id"));
                String code = item.attributeValue("code");
                if (id == 3L) {
                    continue;
                }
                languages.put(id, Locale.forLanguageTag(code));
            }
        } catch (Exception e) {
            log.error("Error while building language map");
        }
    }

    public static String getLabelFileName(Locale l) {
        String name = APP_RESOURCES_EN;
        if (!Locale.ENGLISH.equals(l)) {
            name = String.format(APP_RESOURCES, l.toLanguageTag().replace('-', '_'));
        }
        return name;
    }

    private static void storeLabels(Locale l) throws Exception {
        Document d = XmlExport.createDocument();
        Element r = XmlExport.createRoot(d);
        List<StringLabel> labels = labelCache.get(l);
        for (StringLabel sl : labels) {
            r.addElement(ENTRY_ELEMENT).addAttribute(KEY_ATTR, sl.getKey()).addCDATA(sl.getValue());
        }
        URL u = APP.getResource(getLabelFileName(l));
        XmlExport.toXml(new File(u.toURI()), d);
    }

    public static void upload(Locale l, InputStream is) throws Exception {
        List<StringLabel> labels = getLabels(is);
        URL u = APP.getResource(getLabelFileName(Locale.ENGLISH)); //get the URL of existing resource
        File el = new File(u.toURI());
        File f = new File(el.getParentFile(), getLabelFileName(l));
        if (!f.exists()) {
            f.createNewFile();
        }
        labelCache.put(l, labels);
        storeLabels(l);
    }

    private static List<StringLabel> getLabels(Locale l) {
        List<StringLabel> labels = new ArrayList<StringLabel>();
        try (InputStream is = APP.getResourceAsStream(getLabelFileName(l))) {
            labels = getLabels(is);
        } catch (Exception e) {
            log.error("Error reading resources document", e);
        }
        return labels;
    }

    private static List<StringLabel> getLabels(InputStream is) throws Exception {
        final List<StringLabel> labels = new ArrayList<StringLabel>();
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        try {
            SAXParser parser = spf.newSAXParser();
            XMLReader xr = parser.getXMLReader();
            xr.setContentHandler(new ContentHandler() {
                StringLabel label = null;

                @Override
                public void startPrefixMapping(String prefix, String uri) throws SAXException {
                }

                @Override
                public void startElement(String uri, String localName, String qName, Attributes atts)
                        throws SAXException {
                    if (ENTRY_ELEMENT.equals(localName)) {
                        label = new StringLabel(atts.getValue(KEY_ATTR), "");
                    }
                }

                @Override
                public void startDocument() throws SAXException {
                }

                @Override
                public void skippedEntity(String name) throws SAXException {
                }

                @Override
                public void setDocumentLocator(Locator locator) {
                }

                @Override
                public void processingInstruction(String target, String data) throws SAXException {
                }

                @Override
                public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
                }

                @Override
                public void endPrefixMapping(String prefix) throws SAXException {
                }

                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    if (ENTRY_ELEMENT.equals(localName)) {
                        labels.add(label);
                    }
                }

                @Override
                public void endDocument() throws SAXException {
                }

                @Override
                public void characters(char[] ch, int start, int length) throws SAXException {
                    StringBuilder sb = new StringBuilder(label.getValue());
                    sb.append(ch, start, length);
                    label.setValue(sb.toString());
                }
            });
            xr.parse(new InputSource(is));
        } catch (Exception e) {
            throw e;
        }
        return labels;
    }

    private static List<StringLabel> getLabels(Locale l, final String search) {
        if (!labelCache.containsKey(l)) {
            List<StringLabel> ll = getLabels(l);
            if (ll != null) {
                labelCache.putIfAbsent(l, ll);
            }
        }
        List<StringLabel> result = new ArrayList<>(
                labelCache.containsKey(l) ? labelCache.get(l) : new ArrayList<StringLabel>());
        if (!Strings.isEmpty(search)) {
            CollectionUtils.filter(result, new Predicate<StringLabel>() {
                @Override
                public boolean evaluate(StringLabel o) {
                    return o != null && (o.getKey().contains(search) || o.getValue().contains(search));
                }
            });
        }
        return result;
    }

    @Override
    public StringLabel get(long id) {
        throw new RuntimeException("Should not be used");
    }

    @Override
    public StringLabel get(Long id) {
        throw new RuntimeException("Should not be used");
    }

    @Override
    public List<StringLabel> get(int start, int count) {
        throw new RuntimeException("Should not be used");
    }

    @Override
    public List<StringLabel> get(String search, int start, int count, String order) {
        throw new RuntimeException("Should not be used");
    }

    public List<StringLabel> get(Locale l, final String search, int start, int count,
            final SortParam<String> sort) {
        List<StringLabel> result = getLabels(l, search);
        if (sort != null) {
            Collections.sort(result, new Comparator<StringLabel>() {
                @Override
                public int compare(StringLabel o1, StringLabel o2) {
                    int val = 0;
                    if (KEY_ATTR.equals(sort.getProperty())) {
                        try {
                            int i1 = Integer.parseInt(o1.getKey()), i2 = Integer.parseInt(o2.getKey());
                            val = i1 - i2;
                        } catch (Exception e) {
                            val = o1.getKey().compareTo(o2.getKey());
                        }
                    } else {
                        val = o1.getValue().compareTo(o2.getValue());
                    }
                    return (sort.isAscending() ? 1 : -1) * val;
                }
            });
        }
        return result.subList(start, start + count > result.size() ? result.size() : start + count);
    }

    @Override
    public long count() {
        throw new RuntimeException("Should not be used");
    }

    @Override
    public long count(String search) {
        throw new RuntimeException("Should not be used");
    }

    public long count(Locale l, final String search) {
        return getLabels(l, search).size();
    }

    @Override
    public StringLabel update(StringLabel entity, Long userId) {
        throw new RuntimeException("Should not be used");
    }

    public StringLabel update(Locale l, StringLabel entity) throws Exception {
        List<StringLabel> labels = labelCache.get(l);
        if (!labels.contains(entity)) {
            labels.add(entity);
            keys.add(entity.getKey());
        }
        storeLabels(l);
        return entity;
    }

    @Override
    public void delete(StringLabel entity, Long userId) {
        throw new RuntimeException("Should not be used");
    }

    public void delete(Locale l, StringLabel entity) throws Exception {
        List<StringLabel> labels = labelCache.get(l);
        if (labels.contains(entity)) {
            labels.remove(entity);
            keys.remove(entity.getKey());
            storeLabels(l);
        }
    }

    public static void delete(Locale l) {
        for (Map.Entry<Long, Locale> e : languages.entrySet()) {
            if (e.getValue().equals(l)) {
                languages.remove(e.getKey());
                break;
            }
        }
        labelCache.remove(l);
        try {
            URL u = APP.getResource(getLabelFileName(l));
            if (u != null) {
                File f = new File(u.toURI());
                if (f.exists()) {
                    f.delete();
                }
            }
        } catch (Exception e) {
            log.error("Unexpected error while deleting language", e);
        }
    }
}