1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.team.internal.ccvs.core.syncinfo;
15 
16 import java.net.InetAddress;
17 import java.net.UnknownHostException;
18 import java.text.ParseException;
19 import java.util.Date;
20 
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.osgi.util.NLS;
24 import org.eclipse.team.internal.ccvs.core.*;
25 import org.eclipse.team.internal.ccvs.core.util.CVSDateFormatter;
26 import org.eclipse.team.internal.ccvs.core.util.Util;
27 
28 /**
29  * This class contains the information required by the server for edit/unedit.
30  */
31 public class NotifyInfo {
32 
33 	// constants for the notifiation type and watches
34 	public static final char EDIT = 'E';
35 	public static final char UNEDIT = 'U';
36 	public static final char COMMIT = 'C';
37 	public static final char[] ALL = new char[] {EDIT, UNEDIT, COMMIT};
38 
39 	protected static final String TAB_SEPARATOR = "\t"; //$NON-NLS-1$
40 
41 	private String filename;
42 	private char notificationType;
43 	private Date timeStamp;
44 	private char[] watches;
45 
46 	/**
47 	 * Constructor for setting all variables
48 	 */
NotifyInfo(String filename, char notificationType, Date timeStamp, char[] watches)49 	public NotifyInfo(String filename, char notificationType, Date timeStamp, char[] watches) {
50 
51 		this.filename = filename;
52 		this.notificationType = notificationType;
53 		this.timeStamp = timeStamp;
54 		this.watches = watches;
55 	}
56 
57 	/**
58 	 * Constructor for a line from the CVS/Notify file
59 	 * @param line
60 	 */
NotifyInfo(IContainer parent, String line)61 	public NotifyInfo(IContainer parent, String line) throws CVSException {
62 		String[] strings = Util.parseIntoSubstrings(line, ResourceSyncInfo.SEPARATOR);
63 		if(strings.length != 4) {
64 			IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR_LINE, NLS.bind(CVSMessages.NotifyInfo_MalformedLine, new String[] { line }), parent);
65 			throw new CVSException(status);
66 		}
67 		this.filename = strings[0];
68 
69 		String type = strings[1];
70 		if (type.length() != 1) {
71 			IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR_LINE, NLS.bind(CVSMessages.NotifyInfo_MalformedNotificationType, new String[] { line }), parent);
72 			throw new CVSException(status);
73 		}
74 		this.notificationType = type.charAt(0);
75 
76 		String date = strings[2];
77 		try {
78 			this.timeStamp = CVSDateFormatter.entryLineToDate(date);
79 		} catch(ParseException e) {
80 			IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR_LINE, NLS.bind(CVSMessages.NotifyInfo_MalformedNotifyDate, new String[] { line }), parent);
81 			throw new CVSException(status);
82 		}
83 
84 		String watchesString = strings[3];
85 		if (watchesString.length() > 0) {
86 			this.watches = new char[watchesString.length()];
87 			for (int i = 0; i < watchesString.length(); i++) {
88 				watches[i] = watchesString.charAt(i);
89 			}
90 		} else {
91 			this.watches = null;
92 		}
93 	}
94 
95 	/**
96 	 * Answer a Sting formatted to be written to the CVS/Notify file.
97 	 *
98 	 * XXX NOTE: This is a guess at the local format. Need to obtain proper format
99 	 *
100 	 * @return String
101 	 */
getNotifyLine()102 	public String getNotifyLine() {
103 		StringBuilder buffer = new StringBuilder();
104 		buffer.append(getName());
105 		buffer.append(ResourceSyncInfo.SEPARATOR);
106 		buffer.append(notificationType);
107 		buffer.append(ResourceSyncInfo.SEPARATOR);
108 		buffer.append(CVSDateFormatter.dateToEntryLine(timeStamp));
109 		buffer.append(ResourceSyncInfo.SEPARATOR);
110 		if (watches != null) {
111 			for (int i = 0; i < watches.length; i++) {
112 				char c = watches[i];
113 				buffer.append(c);
114 			}
115 		}
116 		return buffer.toString();
117 	}
118 
119 	/**
120 	 * Answer a Sting formatted to be sent to the server.
121 	 *
122 	 * @return String
123 	 */
getServerLine(ICVSFolder parent)124 	public String getServerLine(ICVSFolder parent) throws CVSException {
125 		StringBuilder buffer = new StringBuilder();
126 		buffer.append(notificationType);
127 		buffer.append(TAB_SEPARATOR);
128 		buffer.append(getServerTimestamp());
129 		buffer.append(TAB_SEPARATOR);
130 		buffer.append(getHost());
131 		buffer.append(TAB_SEPARATOR);
132 		buffer.append(getWorkingDirectory(parent));
133 		buffer.append(TAB_SEPARATOR);
134 		if (watches != null) {
135 			for (int i = 0; i < watches.length; i++) {
136 				char c = watches[i];
137 				buffer.append(c);
138 			}
139 		}
140 		return buffer.toString();
141 	}
142 
143 	/**
144 	 * Answer the timestamp in GMT format.
145 	 * @return String
146 	 */
getServerTimestamp()147 	private String getServerTimestamp() {
148 		return CVSDateFormatter.dateToNotifyServer(timeStamp);
149 	}
150 
151 	/**
152 	 * Answer the working directory for the receiver's file. The format
153 	 * is NOT device dependant (i.e. /'s are used as the path separator).
154 	 *
155 	 * @return String
156 	 */
getWorkingDirectory(ICVSFolder parent)157 	private String getWorkingDirectory(ICVSFolder parent) throws CVSException {
158 		return parent.getIResource().getLocation().toString();
159 	}
160 
161 	/**
162 	 * Answer the host name of the client machine.
163 	 * @return String
164 	 */
getHost()165 	private String getHost() throws CVSException {
166 		try {
167 			return InetAddress.getLocalHost().getHostName();
168 		} catch (UnknownHostException e) {
169 			throw CVSException.wrapException(e);
170 		}
171 	}
172 
173 	/**
174 	 * Answer the name of the file associated with the notification
175 	 * @return String
176 	 */
getName()177 	public String getName() {
178 		return filename;
179 	}
180 
181 	/**
182 	 * Answer the notification type associated with the notification
183 	 * @return char
184 	 */
getNotificationType()185 	public char getNotificationType() {
186 		return notificationType;
187 	}
188 
189 }
190