1/*******************************************************************************
2 * Copyright (c) 2000, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *     IBM Corporation - initial API and implementation
10 *******************************************************************************/
11/*
12 * Created on 8-Jan-2004
13 *
14 * To change this generated comment go to
15 * Window>Preferences>Java>Code Generation>Code Template
16 */
17package org.eclipse.releng;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.FileNotFoundException;
22import java.io.FileWriter;
23import java.io.IOException;
24import java.util.StringTokenizer;
25import java.util.Properties;
26import java.io.PrintWriter;
27
28/**
29 * @author SDimitrov
30 *
31 * This class finds an available build machine by reading a registry of build
32 * machines and their status.
33 *
34 */
35public class BuildMachineManager extends Thread {
36	// registry mapping of machines being used by a given build
37	//list is the path to the configuration of build machines available for a
38	// given build type
39	// waitInterval is the number of seconds to wait if no machines are
40	// available for a given build purpose
41	// findKey represents the key in cfg from which which to obtain the list of
42	// machines
43	// createKey is written to the registry with the machine name that is
44	// available
45
46	private String markerContainer;
47	private int waitInterval;
48	private String markerName;
49	private String markerKey="0";
50	private String cfgKey;
51	private String cfg;
52
53	public BuildMachineManager() {
54		super();
55	}
56	public BuildMachineManager(
57		String cfg,
58		String markerContainer,
59		int waitInterval,
60		String markerName,
61		String markerKey,
62		String cfgKey) {
63		this.waitInterval = waitInterval;
64		this.cfg = cfg;
65		this.markerContainer = markerContainer;
66		this.markerName = markerName;
67		this.markerKey = markerKey;
68		this.cfgKey = cfgKey;
69		this.run();
70	}
71
72	public void run() {
73		String[] machines = getNames();
74
75		if (new File(markerContainer+"/"+markerName+".marker").exists()){
76			System.out.println("Marker already exists: "+markerName+".marker");
77			return;
78		}
79
80		boolean machineFound = false;
81		try {
82			while (!machineFound) {
83				for (int i = 0; i < machines.length; i++) {
84					if (!inUse(machines[i])) {
85						if (createNewMarker(machines[i])) {
86							machineFound = true;
87							return;
88						}
89					}
90				}
91
92				//wait a given interval before re-checking for an available
93				// build machine.
94				sleep(1000 * waitInterval);
95			}
96		} catch (InterruptedException e) {
97			e.printStackTrace();
98		}
99	}
100
101	private boolean createNewMarker(String machineName) {
102		//create a temporary lock on marker container
103
104		File lock = new File(markerContainer + "/" + "lock");
105		if (lock.exists())
106			return false;
107
108		try {
109			File markerFile =  new File(markerContainer+"/"+markerName+".marker");
110			lock.createNewFile();
111			markerFile.createNewFile();
112			PrintWriter out = new PrintWriter(new FileWriter(markerFile));
113			out.println(markerKey+"=" + machineName);
114			out.flush();
115			out.close();
116			lock.delete();
117		} catch (IOException e) {
118			e.printStackTrace();
119			return false;
120		}
121		return true;
122	}
123
124	private boolean inUse(String machineName) {
125
126		File container = new File(markerContainer);
127
128		if (container.exists() && container.isDirectory()) {
129			Properties properties = null;
130			File[] markerFiles = container.listFiles();
131			for (int i = 0; i < markerFiles.length; i++) {
132				File markerFile = markerFiles[i];
133				if (markerFile.getName().endsWith(".marker")) {
134					properties = new Properties();
135					try {
136						FileInputStream in = new FileInputStream(markerFiles[i]);
137						properties.load(in);
138						in.close();
139						if (properties.containsValue(machineName)){
140							return true;
141						}
142					} catch (FileNotFoundException e) {
143						e.printStackTrace();
144					} catch (IOException e) {
145						e.printStackTrace();
146					}
147				}
148			}
149		}
150		return false;
151	}
152
153	private String[] getNames() {
154		StringTokenizer tokenizer = new StringTokenizer(getList(), ",");
155		String[] names = new String[tokenizer.countTokens()];
156		int i = 0;
157
158		while (tokenizer.hasMoreTokens()) {
159			names[i++] = tokenizer.nextToken();
160		}
161		return names;
162	}
163
164	private String getList() {
165		Properties cfgProperties = new Properties();
166		try {
167			FileInputStream in = new FileInputStream(new File(cfg));
168			cfgProperties.load(in);
169			in.close();
170
171		} catch (FileNotFoundException e) {
172			e.printStackTrace();
173		} catch (IOException e) {
174			e.printStackTrace();
175		}
176		return cfgProperties.getProperty(cfgKey);
177	}
178}
179