net.yatomiya.nicherry.services.bbs.ModelUpdateHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.yatomiya.nicherry.services.bbs.ModelUpdateHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2014,2015 Hideki Yatomi
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package net.yatomiya.nicherry.services.bbs;

import java.io.*;
import java.util.*;
import com.squareup.okhttp.*;
import net.yatomiya.e4.services.*;
import net.yatomiya.e4.util.*;
import net.yatomiya.nicherry.*;
import net.yatomiya.nicherry.model.bbs.*;

public abstract class ModelUpdateHandler {
    private ModelProcessor processor;
    private boolean isSynchronous;
    private boolean isForceUpdate;
    private BBSService bbsService;
    private Call httpCall;
    private long executeTime;
    private UpdateEvent updateEvent;
    private EventService eventService;

    public ModelProcessor getProcessor() {
        return processor;
    }

    public MBBSModel getModel() {
        return processor.getModel();
    }

    public File getStorageDirectory() {
        return getProcessor().getManager().getStorageDirectory(getModel().getId());
    }

    public BBSHttpClient getHttpClient() {
        return bbsService.getHttpClient();
    }

    public boolean isSynchronous() {
        return isSynchronous;
    }

    public boolean isForceUpdate() {
        return isForceUpdate;
    }

    public UpdateEvent getUpdateEvent() {
        return updateEvent;
    }

    public long getExecuteTime() {
        return executeTime;
    }

    public Call execute(ModelProcessor processor, boolean isSynchronous, boolean isForceUpdate) {
        this.processor = processor;
        this.isSynchronous = isSynchronous;
        this.isForceUpdate = isForceUpdate;
        bbsService = processor.getManager().getBBSService();

        executeTime = JUtils.getCurrentTime();

        BBSHttpClient client = bbsService.getHttpClient();

        Request request = createRequestBuilder().build();

        updateEvent = createUpdateEvent();
        updateEvent.setModel(getModel());
        updateEvent.setRequest(request);

        EUtils.get(EventService.class).send(BBSService.Event.Update.START, getModel());

        Callback callback = new Callback() {
            @Override
            public void onResponse(Response response) throws IOException {
                doOnResponse(response);
            }

            @Override
            public void onFailure(Request request, IOException e) {
                doOnFailure(request, e);
            }
        };
        httpCall = client.execute(request, callback, isSynchronous);

        return httpCall;
    }

    protected abstract UpdateEvent createUpdateEvent();

    protected Request.Builder createRequestBuilder() {
        MBBSModel model = getModel();
        HttpUrl url = HttpUrl.parse(createRequestUrl());
        Request.Builder builder = HttpUtils.createRequestBuilder(url,
                isForceUpdate ? null : new Date(model.getLastModifiedInResponseHeader()));
        builder.tag(this);

        return builder;
    }

    protected String createRequestUrl() {
        return getModel().getUrl();
    }

    private void doOnResponse(Response response) throws IOException {
        if (httpCall.isCanceled())
            throw new IOException("Canceled");

        updateEvent.setResponse(response);

        boolean doForeground = false;
        if (handleValidateResponse(response)) {
            if (handleBackground(response)) {
                doForeground = true;
            }
        }

        if (doForeground) {
            EUtils.asyncExec(() -> {
                if (bbsService.isDisposed())
                    return;

                try {
                    Date lastModified = response.headers().getDate("Last-Modified");
                    getModel().setLastModifiedInResponseHeader(lastModified == null ? -1 : lastModified.getTime());

                    if (handleForeground()) {
                        MBBSModel model = getModel();
                        model.setLastUpdateTime(model.getUpdateTime());
                        model.setUpdateTime(JUtils.getCurrentTime());

                        processor.save();

                        updateEvent.setType(UpdateEvent.Type.UPDATED);
                    }
                } catch (IOException e) {
                    updateEvent.setType(UpdateEvent.Type.UNKNOWN_ERROR);
                    updateEvent.setException(e);
                }

                handleFinished();
            });
        } else {
            handleFinished();
        }
    }

    private void doOnFailure(Request request, IOException e) {
        updateEvent.setType(UpdateEvent.Type.CONNECTION_ERROR);
        updateEvent.setException(e);

        handleException(request, e);
        handleFinished();
    }

    protected boolean handleValidateResponse(Response response) {
        switch (response.code()) {
        case 200: // OK
            return true;
        case 304: // Not_Modified
            updateEvent.setType(UpdateEvent.Type.NOT_MODIFIED);
            return false;
        default:
            updateEvent.setType(UpdateEvent.Type.STATUS_ERROR);
            return false;
        }
    }

    protected boolean handleBackground(Response response) throws IOException {
        return true;
    }

    protected boolean handleForeground() throws IOException {
        return true;
    }

    protected void handleException(Request request, IOException e) {
    }

    protected void handleFinished() {
        EUtils.asyncExec(() -> {
            if (bbsService.isDisposed())
                return;

            processor.updateFinished(getUpdateEvent());

            EUtils.get(EventService.class).send(BBSService.Event.Update.END, getUpdateEvent());

            {
                String msg = "";
                switch (getUpdateEvent().getType()) {
                case UPDATED:
                    msg = "????";
                    break;
                case NOT_MODIFIED:
                    msg = "?????";
                    break;
                case STATUS_ERROR:
                case CONNECTION_ERROR:
                case UNKNOWN_ERROR:
                    msg = "?????";
                    break;
                }

                if (!JUtils.isEmpty(msg)) {
                    msg = msg + " " + BBSUtils.getPathName(getModel());
                    msg = msg + " " + getFinishedAnnounceMessage();
                    NUtils.announce(msg);
                }
            }
        });
    }

    protected abstract String getFinishedAnnounceMessage();
}