/** * @param xcomputer * @return * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ private boolean addComputer(final ComputerRemote xcomputer) { if (xcomputer == null || computer == null) { View.print(getClass() + "Fehler."); return false; } for (int i = 0; i < computer.size(); i++) { // // In case the computer has already been added or the computer to add // is the local computer, return false. if (xcomputer.matches(computer.get(i))) { return false; } else if (xcomputer.getUid().equals(getUid())) { return false; } } Staticio.skipPort(xcomputer.getPort()); computer.add(xcomputer); setChanged(); notifyObservers(new Object[] {View.ID_UPDATE_COMPUTER, computer}); save(Constants.getConfigLocal()); return true; }
private void removeTasklock(final String xoldid) { final String newId = taskLock.remove(0); if (!newId.equals(xoldid)) { View.print("Fatal error in removing task lock" + xoldid + ". removed " + newId); } }
/** * Initialize a new (local) repository which will be provided to remote computers afterwards. * * @param xpath the path to the repository at local computer * @param xdescription Description of the repository (is stored inside the repository's * configuration file) * @param xname the repository's name. * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public boolean initializeRepository( final String xpath, final String xdescription, final String xname) { // // Create folder and call the initialize - script. final boolean success = new File(xpath).mkdirs(); final boolean success3 = Utils.callScript( Constants.UNIX_SRC_GIT_INIT, Constants.UNIX_DEST_GIT_INIT.getAbsolutePath(), xpath + " " + xname, true); if (!success3) { // Inform the user on the failure View.print( "Failed to create repository " + xname + " at " + xpath + ":\n" + "\tSuccess creating folder: " + success + "\tSuccess executing script: " + success3); } else { // // Inform the user on the success, add new repository and link to the // suitable vectors View.print("Successfully created repository " + xname + " at " + xpath + "."); final Repository rep = new Repository(xname, new Random().nextDouble(), xdescription); addRepository(rep); addLink(new Link(xpath, this, rep)); // // inform the remote computers on the new computer broadcastInformation(); } return success3; }
/** * Handle HI message. * * @param xaddr */ public final void handleHi(final String xaddr, final String xuid) { for (int i = 0; i < computer.size(); i++) { if (computer.get(i).getAddress().equals(xaddr) && computer.get(i).getUid().equals(xuid)) { computer.get(i).setContacted(); } else if (computer.get(i).getAddress().equals(xaddr) || computer.get(i).getUid().equals(xuid)) { View.print("Wrong computer UID or address."); computer.get(i).setConnected(false); } } }
/** * Save the instance of {@link #ComputerLocal(String)} to the specified location. * * @param xconfigLocal the specified location * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public void save(final File xconfigLocal) { final GitThread t = gitThread; gitThread = null; ObjectOutputStream oos; try { FileOutputStream fos = new FileOutputStream(xconfigLocal); oos = new ObjectOutputStream(fos); oos.writeObject(this); oos.flush(); oos.close(); } catch (IOException e) { View.print( "The configuration could not be saved because the " + "folder does not exist: " + e); } gitThread = t; }
/** * @param xrepository * @return * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ private boolean addRepository(final Repository xrepository) { if (xrepository == null || repositories == null) { View.print(getClass() + "Fehler."); return false; } for (int i = 0; i < repositories.size(); i++) { if (xrepository.matches(repositories.get(i))) { return false; } } repositories.add(xrepository); setChanged(); notifyObservers(new Object[] {View.ID_UPDATE_REPO, repositories}); save(Constants.getConfigLocal()); return true; }
/** * @param xlink * @return * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ private boolean addLink(final Link xlink) { if (xlink == null || combination == null) { View.print(getClass() + "Fehler."); return false; } for (int i = 0; i < combination.size(); i++) { if (xlink.matches(combination.get(i))) { return false; } } combination.add(xlink); setChanged(); notifyObservers(new Object[] {View.ID_UPDATE_LINK, combination}); save(Constants.getConfigLocal()); return true; }
/** * This function is called once for starting to scan for other copies of the program inside the * local network. It generates {@value #amountOfThreads} threads by calling the private method * {@link #getNewClient(int, int, int, ComputerLocal)}. * * @param xcl instance of the Local Computer class that handles the received information - * strings. * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public static void startScanning(final ComputerLocal xcl) { // // In case local testing is enabled, do not scan for remote computers // but use the local IP and given port. if (Constants.isLocalTesting()) { requestLocalServerInformation(xcl); } else { // // Initialize the Vector which contains information on the current // process of each XTreaead that is created in the following. currentProgress = new Vector<Integer>(); // // Print information message and compute the range of one thread. // Afterwards initialize #amountOfThreads threads by calling the method // #getNewClient. View.print("Start scanning for clients in " + amountOfThreads + " Threads."); final int threadRange = (Constants.globalPortEnd - Constants.globalPortStart) / amountOfThreads; int sum = Constants.globalPortStart; for (int i = 0; i < amountOfThreads; i++) { // Add the lower range of scanning of the client to the progress vector // and generate upper range by adding the threadRange. currentProgress.add(sum); int sump = sum + threadRange; // Create new client and set the sum - integer to the upper range of // the current process. getNewClient(i, sum, sump, xcl); sum = sump; } } }
/** * @param xia * @param xport * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public final void generateAddclientTask(final InetAddress xia, final int xport) { // If the address - port combination is unknown, generate new task to add // the client boolean found = false; for (int i = 0; i < computer.size(); i++) { if (computer.get(i).getAddress().equals(xia.getHostAddress())) { found = true; if (xport != computer.get(i).getPort()) { computer.get(i).setPort(xport); View.print( "Stored wrong port identifier for client with ip " + computer.get(i).getAddress()); } } } // // In case the remote computer has not already been added, create new // instance of TaskAddclient. if (!found) { taskList.add(new TaskAddclient(this, xia, xport)); } }
/** * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public void run() { while (!isInterrupted()) { if (taskList.isEmpty() && getCombination().isEmpty()) { try { Thread.sleep(2000); } catch (InterruptedException e) { interrupt(); } } // // // Check if the connection is established to all the RemoteComputers // that are listed as online final double currentTime = System.currentTimeMillis(); for (int i = 0; i < computer.size(); i++) { final double dueTime = computer.get(i).getDueContact(); final double connectionTime = computer.get(i).getContactionThreshold(); if (computer.get(i).isConnected()) { if (currentTime > connectionTime) { computer.get(i).setConnected(false); Staticio.unskipPort(computer.get(i).getPort()); setChanged(); notifyObservers(new Object[] {View.ID_UPDATE_COMPUTER, computer}); } else if (currentTime > dueTime) { computer.get(i).sayHi(ComputerLocal.this); System.out.println("sayin hi"); } else { System.out.println("hier" + (currentTime - computer.get(i).getLastContact())); } } } final int taskListSize = taskList.size(); final int totalNumber = taskList.size() + getCombination().size(); final String identifier = "GitThreadRun" + new Random().nextDouble() + " " + System.currentTimeMillis(); taskLock.add(identifier); if (!taskLock.get(0).equals(identifier)) { View.print( "DEBUG: taskLock.get(0) equalt nicht identifier!" + taskLock.get(0) + ".." + identifier); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } continue; } for (int i = 0; i < taskList.size(); i++) { setPercentage(1.0 * i / totalNumber); if (taskList.get(i).isReadyPerformOperation()) { removeTask(i); i--; } } setChanged(); notifyObservers(new Object[] {View.ID_UPDATE_TASKS, taskList, taskListfinished}); for (int i = 0; i < getCombination().size(); i++) { setPercentage(1.0 * (taskListSize + i) / totalNumber); // // if the current combination contains a repository which // is contained by the local Computer check whether changes // occurred. If that is the case, send information message // to all participants of the repository. final Link currentLink = getCombination().get(i); final Repository repo = currentLink.getRepository(); final double timestamp = System.currentTimeMillis(); if (currentLink.getComputer().getUid().equals(getUid())) { final String repoPath = currentLink.getPath(); final String commitMsg = "auto" + timestamp; if (Utils.callScript( Constants.UNIX_SRC_GIT_COMMIT, Constants.UNIX_DEST_GIT_COMMIT.getAbsolutePath(), repoPath + " " + commitMsg, true)) { // // Inform the user about the changes View.print("git changes occurred at " + repoPath); } else { continue; } // Find all the computers connected ot the final Vector<Link> vec_parti = (Vector<Link>) fetchTaskupdateParticipants(repo.getUid())[0]; // important: initialize TaskUpdate before sending // signal. TaskUpdate tu = new TaskUpdate(vec_parti, currentLink, ComputerLocal.this); if (!tu.add( TaskUpdate.generateInformationString( repo.getUid(), ComputerLocal.this.getUid(), "" + timestamp))) { View.print( "Error: new created task does not accept " + "information on the local computer."); } taskList.add(tu); // // Inform every client that is online to update the repository. for (int j = 0; j < vec_parti.size(); j++) { ((ComputerRemote) vec_parti.get(j).getComputer()) .repositoryUpdated(getUid(), repo.getUid(), timestamp); } } } removeTasklock(identifier); try { Thread.sleep(1000); } catch (InterruptedException e) { View.print("interrupted"); interrupt(); } } }
/** * Generate information string on the local computer configuration (includes {@link #computer}, * {@link #repositories}, {@link #combination}). * * @return whether new changes have occurred due to the update. * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public boolean convertInformationString(final String xstring, final String xadr) { // go through all the identifiers and generate Vector of Computers, // Repositories and Link-Combinations boolean changesOccurred = false; // // Fetch information from string final int occurr1 = xstring.indexOf(Utils.invalidCharLevel1); final String remoteUid = xstring.substring(0, occurr1); final String rest00 = xstring.substring(occurr1 + 1, xstring.length()); final String port = rest00.substring(0, rest00.indexOf(Utils.invalidCharLevel1)); final int iport = Integer.parseInt(port); boolean found = false; for (int i = 0; i < computer.size(); i++) { if (computer.get(i).getUid().equals(remoteUid)) { found = true; if (computer.get(i).getPort() != iport || computer.get(i).getAddress().equals(xadr) || computer.get(i).isConnected() == false) { changesOccurred = true; } computer.get(i).setPort(iport); computer.get(i).setAddress(xadr); computer.get(i).setConnected(true); computer.get(i).setContacted(); } } // if the computer has not been found inside the list of computers, add // it. if (!found) { ComputerRemote cr = new ComputerRemote(remoteUid, xadr, iport); cr.setConnected(true); addComputer(cr); changesOccurred = true; cr.setContacted(); } // TODO: Check whether the computer with the UID has already been added // to the list of computers. String remainingString = xstring.substring(remoteUid.length() + port.length() + 2, xstring.length()); String strgComputer = remainingString.substring(0, remainingString.indexOf(Utils.invalidCharLevel1)); remainingString = remainingString.substring(strgComputer.length() + 1, remainingString.length()); String strgRepositories = remainingString.substring(0, remainingString.indexOf(Utils.invalidCharLevel1)); remainingString = remainingString.substring(strgRepositories.length() + 1, remainingString.length()); String strgCombination = remainingString; // // ComputerRemote for (int i = strgComputer.indexOf(Utils.invalidCharLevel2); i != -1; i = strgComputer.indexOf(Utils.invalidCharLevel2)) { final String strgComputerSingle = strgComputer.substring(0, i); strgComputer = strgComputer.substring(i + 1, strgComputer.length()); ComputerRemote comp = ComputerRemote.convertInformationString(strgComputerSingle); changesOccurred = addComputer(comp) || changesOccurred; } // // Repository for (int i = strgRepositories.indexOf(Utils.invalidCharLevel2); i != -1; i = strgRepositories.indexOf(Utils.invalidCharLevel2)) { final String strgSingle = strgRepositories.substring(0, i); strgRepositories = strgRepositories.substring(i + 1, strgRepositories.length()); Repository repo = Repository.convertInformationString(strgSingle); changesOccurred = addRepository(repo) || changesOccurred; } // // Links // Important: the Links can ony be added to the vector of for (int i = strgCombination.indexOf(Utils.invalidCharLevel2); i != -1; i = strgCombination.indexOf(Utils.invalidCharLevel2)) { final String strgSingle = strgCombination.substring(0, i); strgCombination = strgCombination.substring(i + 1, strgCombination.length()); Link clink = Link.convertInformationString(strgSingle, repositories, computer); changesOccurred = addLink(clink) || changesOccurred; } View.print("Something changed: " + changesOccurred); if (changesOccurred) { changed(); } // Return whether the above-created computers, combinations and // repositories have been already added to list. return changesOccurred; }
/** * Create new instance of TaskUpdate from received message * * @param xmessageRest * @return * @author Julius Huelsmann * @version %I%, %U% * @since 1.0 */ public final synchronized boolean newTaskUpdate(final String xmessageRest) { // // Enable task-lock. final String identifier = "newTaskUpdate" + new Random().nextDouble() + " " + System.currentTimeMillis(); taskLock.add(identifier); // // In case the task is not locked, continue. Otherwise go to else clause // that waits for a few milliseconds and recalls the function afterwards. if (taskLock.get(0).equals(identifier)) { // // Check if task already exists that is working with the same repository // and add string to the task. May occur here due to task-lock-delay. if (forewardTaskMessage(xmessageRest)) { return true; } // // Here it is clear that the task does not exist and that a new task has // to be created. Thus save the current time as an identifier of the // update time. double timestamp = System.currentTimeMillis(); final String[] extractedInfo = TaskUpdate.fetchInformation(xmessageRest); final String repoUid = extractedInfo[0]; // // Fetch participants of the new task for creating the task. Object[] o = fetchTaskupdateParticipants(repoUid); final Vector<Link> vec_parti = (Vector<Link>) o[0]; final Link ownRepoLink = (Link) o[1]; if (ownRepoLink != null && !vec_parti.isEmpty()) { final String repoPath = ownRepoLink.getPath(); final String commitMsg = "auto" + timestamp; if (!Utils.callScript( Constants.UNIX_SRC_GIT_COMMIT, Constants.UNIX_DEST_GIT_COMMIT.getAbsolutePath(), repoPath + " " + commitMsg, true)) { timestamp = TaskUpdate.VALUE_NO_UPDATE; } else { View.print( getClass().getSimpleName() + " Error. local computer " + "out of sync?" + ownRepoLink + vec_parti.isEmpty()); } final TaskUpdate tu = new TaskUpdate(vec_parti, ownRepoLink, this); taskList.add(tu); if (!tu.add(xmessageRest)) { View.print("ERROR in COMPUTERLOCAL COULD NOT ADD " + xmessageRest); final String newId = taskLock.remove(0); if (!newId.equals(identifier)) { View.print("Fatal error in newTaksupdate 1"); } return false; } final String myself = Task.COMMUNIICATION_CHANGES + ownRepoLink.getRepository().getUid() + Utils.invalidCharLevel1 + getUid() + Utils.invalidCharLevel1 + timestamp; if (!tu.add(myself)) { View.print("ERROR in COMPUTERLOCAL COULD NOT ADD " + xmessageRest); final String newId = taskLock.remove(0); if (!newId.equals(identifier)) { View.print("Fatal error in newTaksupdate 2"); } return false; } final String newId = taskLock.remove(0); if (!newId.equals(identifier)) { View.print("Fatal error in newTaksupdate 3"); } return true; } // update participants final String newId = taskLock.remove(0); if (!newId.equals(identifier)) { View.print("Fatal error in newTaksupdate 4"); } return false; } else { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } return newTaskUpdate(xmessageRest); } }