com.nominanuda.solr.DataImportHandlerWs.java Source code

Java tutorial

Introduction

Here is the source code for com.nominanuda.solr.DataImportHandlerWs.java

Source

/*
 * Copyright 2008-2011 the original author or authors.
 * 
 * Licensed 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 com.nominanuda.solr;

import static com.nominanuda.dataobject.DataStructHelper.STRUCT;
import static com.nominanuda.lang.Check.illegalargument;
import static com.nominanuda.web.http.HttpCoreHelper.HTTP;

import java.io.CharArrayWriter;
import java.io.StringReader;

import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.xml.sax.InputSource;

import com.nominanuda.code.Nullable;
import com.nominanuda.dataobject.DataArray;
import com.nominanuda.dataobject.DataObject;
import com.nominanuda.dataobject.JsonXmlReader;
import com.nominanuda.dataobject.SimpleJsonXmlTransformer;
import com.nominanuda.lang.InstanceFactory;
import com.nominanuda.urispec.URISpec;
import com.nominanuda.web.http.Http500Exception;
import com.nominanuda.web.http.HttpProtocol;
import com.nominanuda.web.mvc.DataObjectURISpec;
import com.nominanuda.web.mvc.WebService;
import com.nominanuda.xml.SAXPipeline;

public abstract class DataImportHandlerWs implements WebService, HttpProtocol {
    private static final String FAKE_ID = "foobar";
    private static final DateTimeFormatter GMT_SOLR_FMT = DateTimeFormat.forPattern("yyyy-MM-dd' 'HH:mm:ss")
            .withZone(DateTimeZone.UTC);
    private static final DateTimeFormatter LOCAL_SOLR_FMT = DateTimeFormat.forPattern("yyyy-MM-dd' 'HH:mm:ss");
    //compulsory conf
    private URISpec<DataObject> uriSpec;
    private String nextUrlPrefix;
    //defaulted conf
    private int rows = 100;
    private String idField = "id";
    private String startUrlParam = "start";
    private String fullImportUrlParam = "fullImport";
    private String sinceUrlParam = "since";
    private String typeUrlParam = "type";
    private String jsonField = null;//"__RAWJSON__";
    private String resultsTag = "results";
    private boolean solrTimestampInLocalTime = true;
    private final SAXPipeline pipe = new SAXPipeline()
            .add(new InstanceFactory<TransformerHandler>(new SimpleJsonXmlTransformer("root"))).complete();

    protected String computeNextUrl(DataObject cmd, Integer nextStart) {
        DataObject params = STRUCT.clone(cmd);
        params.put(startUrlParam, nextStart.toString());
        return nextUrlPrefix + uriSpec.template(params);
    }

    protected abstract DataArray computeDeleted(DataObject cmd, String type_, long since, int start, int rows);

    protected abstract DataArray computeAddedOrModified(DataObject cmd, String type_, long since, int start,
            int rows);

    private long decodeSinceDate(@Nullable String sinceStr) {
        if (sinceStr == null) {
            return 0;
        } else {
            long dt = solrTimestampInLocalTime ? LOCAL_SOLR_FMT.parseDateTime(sinceStr).getMillis()
                    : GMT_SOLR_FMT.parseDateTime(sinceStr).getMillis();
            return dt;
        }
    }

    public HttpResponse handle(HttpRequest request) throws Exception {
        try {
            DataObject cmd = illegalargument.assertNotNull(uriSpec.match(request.getRequestLine().getUri()));
            String type_ = (String) cmd.getStrict(typeUrlParam);
            long since = decodeSinceDate(cmd.getString(sinceUrlParam));
            boolean fullImport = Boolean.valueOf(cmd.getString(fullImportUrlParam));
            String startParam = cmd.getString(startUrlParam);
            int start = startParam == null ? 0 : Integer.valueOf(startParam);
            if (fullImport) {
                since = 0;
            }
            DataArray resultsArray = computeAddedOrModified(cmd, type_, since, start, rows);
            if (jsonField != null) {
                for (Object record : resultsArray) {
                    DataObject o = (DataObject) record;
                    if (!o.exists(jsonField)) {
                        o.put(jsonField, o.toString());
                    }
                }
            }
            int resLen = resultsArray.getLength();
            DataArray deletedEntities = computeDeleted(cmd, type_, since, start, rows);
            for (Object o : deletedEntities) {
                DataObject obj = STRUCT.newObject();
                obj.put(idField, FAKE_ID);
                obj.put("deleteDocById", o.toString());
                resultsArray.add(obj);
            }
            if (resLen >= rows || deletedEntities.getLength() >= rows) {
                Integer nextStart = start + rows;
                DataObject hasMore = resultsArray.addNewObject();
                hasMore.put(idField, "1");
                hasMore.put("hasMore", true);
                hasMore.put("nextUrl", computeNextUrl(cmd, nextStart));
            }
            String message = toXml(STRUCT.newObject().with(resultsTag, resultsArray));
            HttpResponse resp = HTTP.createBasicResponse(200, message, CT_APPLICATION_XML_CS_UTF8);
            return resp;
        } catch (Exception e) {
            throw new Http500Exception(e);
        }
    }

    private String toXml(DataObject o) {
        CharArrayWriter w = new CharArrayWriter();
        pipe.build(new SAXSource(new JsonXmlReader(), new InputSource(new StringReader(o.toString()))),
                new StreamResult(w)).run();
        return new String(w.toCharArray());
    }

    public void setUriSpec(String uriSpec) {
        this.uriSpec = new DataObjectURISpec(uriSpec);
    }

    public void setNextUrlPrefix(String nextUrlPrefix) {
        this.nextUrlPrefix = nextUrlPrefix;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public void setIdField(String idField) {
        this.idField = idField;
    }

    public void setStartUrlParam(String startUrlParam) {
        this.startUrlParam = startUrlParam;
    }

    public void setFullImportUrlParam(String fullImportUrlParam) {
        this.fullImportUrlParam = fullImportUrlParam;
    }

    public void setSinceUrlParam(String sinceUrlParam) {
        this.sinceUrlParam = sinceUrlParam;
    }

    public void setTypeUrlParam(String typeUrlParam) {
        this.typeUrlParam = typeUrlParam;
    }

    public void setJsonField(String jsonField) {
        this.jsonField = jsonField;
    }

    public void setResultsTag(String resultsTag) {
        this.resultsTag = resultsTag;
    }

    public void setSolrTimestampInLocalTime(boolean solrTimestampInLocalTime) {
        this.solrTimestampInLocalTime = solrTimestampInLocalTime;
    }
}