omm.OMMEnhancer.java Source code

Java tutorial

Introduction

Here is the source code for omm.OMMEnhancer.java

Source

package omm;
/*
* 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.
*/

import gate.Document;
import gate.Factory;
import gate.creole.ResourceInstantiationException;
import gate.util.GateException;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import omm.impl.OMMWrapper;
import omm.impl.VariOMapping;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.*;
import org.apache.stanbol.commons.stanboltools.datafileprovider.DataFileListener;
import org.apache.stanbol.commons.stanboltools.datafileprovider.DataFileTracker;
import org.apache.stanbol.enhancer.servicesapi.*;
import org.apache.stanbol.enhancer.servicesapi.helper.ContentItemHelper;
import org.apache.stanbol.enhancer.servicesapi.impl.AbstractEnhancementEngine;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Component(immediate = true, metatype = true, inherit = true)
@Service
@Properties(value = { @Property(name = EnhancementEngine.PROPERTY_NAME, value = "open-mutation-miner") })
public class OMMEnhancer extends AbstractEnhancementEngine implements EnhancementEngine, ServiceProperties {

    /**
     * Using slf4j for logging
     */
    private static final Logger log = LoggerFactory.getLogger(OMMEnhancer.class);
    /* gate files from file provider */
    private static final String GATE_DATA_FILE = "impact.zip";
    private Path gatePath;
    private OMMWrapper ommWrapper;

    /**
     * ServiceProperties are currently only used for automatic ordering of the
     * execution of EnhancementEngines (e.g. by the WeightedChain implementation).
     * Default ordering means that the engine is called after all engines that
     * use a value < {@link org.apache.stanbol.enhancer.servicesapi.ServiceProperties#ORDERING_CONTENT_EXTRACTION}
     * and >= {@link org.apache.stanbol.enhancer.servicesapi.ServiceProperties#ORDERING_EXTRACTION_ENHANCEMENT}.
     */
    public Map getServiceProperties() {
        return Collections.unmodifiableMap(Collections.singletonMap(ENHANCEMENT_ENGINE_ORDERING, ORDERING_DEFAULT));
    }

    @Reference
    private DataFileTracker dataFileTracker;
    private DataFileListener modelFileListener;

    @Override
    protected void activate(ComponentContext context) throws ConfigurationException, Exception {
        super.activate(context);

        modelFileListener = new GateFileListener();
        Map<String, String> properties = new HashMap<String, String>();
        properties.put("Description", "Gate runtime dependencies");
        dataFileTracker.add(modelFileListener, GATE_DATA_FILE, properties);
    }

    @Override
    protected void deactivate(ComponentContext ctx) throws Exception {
        super.deactivate(ctx);
        dataFileTracker.removeAll(modelFileListener); //remove all tracked files
    }

    /**
     * @return if and how (asynchronously) we can enhance a ContentItem
     */
    public int canEnhance(ContentItem ci) throws EngineException {
        // check if content is present
        try {
            if ((ci.getBlob() == null) || (ci.getBlob().getStream().read() == -1)) {
                return CANNOT_ENHANCE;
            }
        } catch (IOException e) {
            log.error("Failed to get the text for " + "enhancement of content: " + ci.getUri(), e);
            throw new InvalidContentException(this, ci, e);
        }
        // todo: configure gate to run asynchronously
        return ENHANCE_SYNCHRONOUS;
    }

    public void computeEnhancements(ContentItem ci) throws EngineException {
        try {
            //get the (generated or submitted) text version of the ContentItem
            Blob textBlob = ContentItemHelper.getBlob(ci, Collections.singleton("text/plain")).getValue();
            String content = ContentItemHelper.getText(textBlob);

            // write content to a temporary file
            File tempInput = File.createTempFile("input", null);
            IOUtils.write(content, FileUtils.openOutputStream(tempInput));

            // run gate wrapper and map output to triples
            try {
                Document document = Factory.newDocument(tempInput.toURI().toURL());
                ommWrapper.execute(document);
                VariOMapping.mapAnnotations(ci, this, document.getAnnotations());
            } catch (ResourceInstantiationException e) {
                log.error("Unable to initialize gate resource", e);
                throw new EngineException("Unable to initialize gate resource", e);
            } catch (GateException e) {
                log.error("Gate exception", e);
                throw new EngineException("Gate exception", e);
            } finally {
                FileUtils.deleteQuietly(tempInput);
            }
        } catch (IOException ex) {
            log.error("Exception reading content item.", ex);
            throw new InvalidContentException("Exception reading content item.", ex);
        }
    }

    /* todo: register service once gate data is unpacked */
    private class GateFileListener implements DataFileListener {
        @Override
        public boolean available(String resourceName, InputStream is) {
            if (resourceName.equals(GATE_DATA_FILE)) {
                log.info(GATE_DATA_FILE + " has become available");
                try {
                    gatePath = unpack(is);
                    ommWrapper = new OMMWrapper(gatePath);
                } catch (IOException e) {
                    log.error("error unpacking " + GATE_DATA_FILE, e);
                } catch (GateException e) {
                    e.printStackTrace();
                }
                return true;
            }
            return false; //keep tracking
        }

        @Override
        public boolean unavailable(String resource) {
            return false; //keep tracking
        }
    }

    public static Path unpack(InputStream zipStream) throws IOException {
        Path unpackedApplication = Files.createTempDirectory("unpacked");

        File file = File.createTempFile("gate", "zip");
        FileUtils.copyInputStreamToFile(zipStream, file);

        try {
            ZipFile zipFile = new ZipFile(file);
            zipFile.extractAll(unpackedApplication.toAbsolutePath().toString());
        } catch (ZipException e) {
            e.printStackTrace();
        }
        log.info("unpacked gate to " + unpackedApplication.toString());
        return unpackedApplication;
    }
}