Java tutorial
/******************************************************************************* * 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(); }