All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jaeksoft.searchlib.replication.ReplicationThread Maven / Gradle / Ivy

Go to download

OpenSearchServer is a powerful, enterprise-class, search engine program. Using the web user interface, the crawlers (web, file, database, ...) and the REST/RESTFul API you will be able to integrate quickly and easily advanced full-text search capabilities in your application. OpenSearchServer runs on Windows and Linux/Unix/BSD.

There is a newer version: 1.5.14
Show newest version
/**   
 * License Agreement for OpenSearchServer
 *
 * Copyright (C) 2010-2012 Emmanuel Keller / Jaeksoft
 * 
 * http://www.open-search-server.com
 * 
 * This file is part of OpenSearchServer.
 *
 * OpenSearchServer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * OpenSearchServer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenSearchServer. 
 *  If not, see .
 **/

package com.jaeksoft.searchlib.replication;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.jaeksoft.searchlib.Client;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.process.ThreadAbstract;
import com.jaeksoft.searchlib.scheduler.TaskLog;
import com.jaeksoft.searchlib.util.FileUtils;
import com.jaeksoft.searchlib.util.InfoCallback;
import com.jaeksoft.searchlib.util.LastModifiedAndSize;
import com.jaeksoft.searchlib.util.ReadWriteLock;
import com.jaeksoft.searchlib.util.RecursiveDirectoryBrowser;
import com.jaeksoft.searchlib.web.PushServlet;

public class ReplicationThread extends ThreadAbstract
		implements RecursiveDirectoryBrowser.CallBack {

	final private ReadWriteLock rwl = new ReadWriteLock();

	private volatile Client client;

	private volatile double totalSize;

	private volatile int filesSent;

	private volatile long bytesSent;

	private volatile double checkedSize;

	private volatile InfoCallback infoCallback;

	private volatile List filesNotPushed;

	private volatile List dirsNotPushed;

	private volatile File sourceDirectory;

	private final ReplicationType replicationType;

	private final long initVersion;

	protected ReplicationThread(Client client,
			ReplicationMaster replicationMaster,
			ReplicationItem replicationItem, InfoCallback infoCallback)
			throws SearchLibException {
		super(client, replicationMaster, replicationItem);
		this.sourceDirectory = replicationItem.getDirectory(client);
		this.replicationType = replicationItem.getReplicationType();
		this.client = client;
		initVersion = client.getIndex().getVersion();
		totalSize = 0;
		filesSent = 0;
		checkedSize = 0;
		filesNotPushed = null;
		dirsNotPushed = null;
		this.infoCallback = infoCallback;
	}

	public int getProgress() {
		rwl.r.lock();
		try {
			if (checkedSize == 0 || totalSize == 0)
				return 0;
			int p = (int) ((checkedSize / totalSize) * 100);
			return p;
		} finally {
			rwl.r.unlock();
		}
	}

	private void incFilesSent(long bytesSent) {
		rwl.w.lock();
		try {
			filesSent++;
			this.bytesSent += bytesSent;
		} finally {
			rwl.w.unlock();
		}
	}

	public ReplicationItem getReplicationItem() {
		return (ReplicationItem) getThreadItem();
	}

	private void initNotPushedList() {
		filesNotPushed = new ArrayList(0);
		dirsNotPushed = new ArrayList(0);
		getReplicationItem().getReplicationType().addNotPushedPath(
				sourceDirectory, filesNotPushed, dirsNotPushed);
	}

	@Override
	public void runner() throws Exception {
		setInfo("Running");
		if (replicationType == ReplicationType.MAIN_DATA_COPY)
			throw new Exception("Not yet implemented");
		else {
			initNotPushedList();
			client.push(this);
		}
	}

	@Override
	public void release() {
		Exception e = getException();
		if (e != null)
			setInfo("Error: " + e.getMessage() != null ? e.getMessage() : e
					.toString());
		else if (isAborted())
			setInfo("Aborted");
		else
			setInfo("Completed");
	}

	public void push() throws SearchLibException {
		ReplicationItem replicationItem = getReplicationItem();
		try {
			setTotalSize(new LastModifiedAndSize(sourceDirectory, false)
					.getSize());
			addCheckedSize(sourceDirectory.length());
			PushServlet.call_init(getReplicationItem());
			new RecursiveDirectoryBrowser(sourceDirectory, this);
			checkVersion();
			switch (replicationItem.getReplicationType().getFinalMode()) {
			case MERGE:
				PushServlet.call_merge(replicationItem);
				break;
			case SWITCH:
				PushServlet.call_switch(replicationItem);
				break;
			}
		} catch (Throwable t) {
			PushServlet.call_abort(replicationItem);
			if (t instanceof SearchLibException)
				throw (SearchLibException) t;
			else
				throw new SearchLibException(t);
		}
	}

	private void setTotalSize(long size) {
		rwl.w.lock();
		try {
			totalSize = size;
		} finally {
			rwl.w.unlock();
		}
	}

	private void addCheckedSize(long length) {
		rwl.w.lock();
		try {
			checkedSize += length;
		} finally {
			rwl.w.unlock();
		}
	}

	final private boolean checkFilePush(final File file) throws IOException {
		if (!checkDirPush(file))
			return false;
		for (File fileNotPushed : filesNotPushed)
			if (file.equals(fileNotPushed))
				return false;
		return true;
	}

	final private boolean checkDirPush(final File dir) throws IOException {
		for (File dirNotPushed : dirsNotPushed) {
			if (dir.equals(dirNotPushed))
				return false;
			if (FileUtils.isSubDirectory(dirNotPushed, dir))
				return false;
		}
		return true;
	}

	public String getStatInfo() {
		rwl.r.lock();
		try {
			return getProgress() + "% completed - " + filesSent
					+ " file(s) sent - "
					+ FileUtils.byteCountToDisplaySize(bytesSent) + " sent";
		} finally {
			rwl.r.unlock();
		}
	}

	private void checkVersion() throws SearchLibException {
		if (initVersion != client.getIndex().getVersion())
			throw new SearchLibException(
					"Replication process aborted. The index has changed.");
	}

	@Override
	public void file(File file) throws SearchLibException {
		try {
			checkVersion();
			ReplicationItem replicationItem = getReplicationItem();
			long length = file.length();
			if (file.isFile()) {
				if (checkFilePush(file)) {
					if (!PushServlet.call_file_exist(client, replicationItem,
							file)) {
						PushServlet.call_file(client, replicationItem, file);
						incFilesSent(length);
					}
				}
			} else {
				if (replicationType.isNotPushedFolder(file))
					dirsNotPushed.add(file);
				if (checkDirPush(file))
					PushServlet.call_directory(client, replicationItem, file);
			}
			addCheckedSize(length);
			if (infoCallback != null) {
				infoCallback.setInfo(getStatInfo());
				if (infoCallback instanceof TaskLog)
					if (((TaskLog) infoCallback).isAbortRequested())
						throw new SearchLibException.AbortException();
			}
		} catch (IllegalStateException e) {
			throw new SearchLibException(e);
		} catch (IOException e) {
			throw new SearchLibException(e);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy