1/*
2 * This file is part of gitg
3 *
4 * Copyright (C) 2012 - Jesse van den Kieboom
5 *
6 * gitg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * gitg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with gitg. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20namespace GitgExt
21{
22
23/**
24 * Message identifier object.
25 *
26 * The message identifier object is used to identify messages sent over the
27 * MessageBus. The message identifier contains an object path and a method.
28 * Both are simple strings and combined describe the location of a message as
29 * a kind of method on an object.
30 *
31 * Valid object paths start with a forward slash and further path elements are
32 * seperated by more forward slashes. The first element needs to start with
33 * an alpha character (or underscore) while further characters can be
34 * alpha numeric or underscores. An example of a valid path is:
35 *
36 * /path/to/object
37 *
38 * Method names on the other hand do not have any restrictions.
39 *
40 */
41public class MessageId : Object
42{
43	/**
44	 * Message object path.
45	 */
46	public string object_path { construct set; get; }
47
48	/**
49	 * Message method.
50	 */
51	public string method { construct set; get; }
52
53	/**
54	 * Full id of the message.
55	 *
56	 * Get the full id of the message identifier. The full id is simply
57	 * <path>.<method>
58	 *
59	 */
60	public string id
61	{
62		owned get { return object_path + "." + method; }
63	}
64
65	/**
66	 * Message hash.
67	 *
68	 * Get a hash for the message identifier suitable for use in a hash table.
69	 * The hash is simply a string hash of the full id of the message identifier.
70	 *
71	 * @return the message identifier hash.
72	 *
73	 */
74	public uint hash()
75	{
76		return id.hash();
77	}
78
79	/**
80	 * Compare two messages for equality.
81	 *
82	 * Compare two messages. Two message identifiers are equal when they have
83	 * the same object path and the same method name.
84	 *
85	 * @param other the message identifier to compare to.
86	 *
87	 * @return true if the message identifiers are equal, false otherwise.
88	 *
89	 */
90	public bool equal(MessageId other)
91	{
92		return id == other.id;
93	}
94
95	/**
96	 * Construct message identifier with object path and method.
97	 *
98	 * Create a new message identifier object with the given object path and
99	 * method name.
100	 *
101	 * @param object_path the object path
102	 * @param method the method name
103	 *
104	 * @return a new message identifier.
105	 *
106	 */
107	public MessageId(string object_path, string method)
108	{
109		Object(object_path: object_path, method: method);
110	}
111
112	/**
113	 * Create a copy of the message identifier.
114	 *
115	 * Create an exact copy of the message identifier.
116	 *
117	 * @return a new message identifier.
118	 *
119	 */
120	public MessageId copy()
121	{
122		return new MessageId(object_path, method);
123	}
124
125	/**
126	 * Check whether an object path is a valid path.
127	 *
128	 * Check whether the given path is a valid object path. A valid object path
129	 * starts with a forward slash, followed by at least one alpha character,
130	 * or underscore. Further valid characters include alphanumeric characters,
131	 * underscores or path separators (forward slash).
132	 *
133	 * Example: /path/to/object
134	 *
135	 * @return true if the specified path is valid, false otherwise
136	 *
137	 */
138	public static bool valid_object_path(string path)
139	{
140		if (path == null)
141		{
142			return false;
143		}
144
145		if (path[0] != '/')
146		{
147			return false;
148		}
149
150		int i = 0;
151
152		while (i < path.length)
153		{
154			var c = path[i];
155
156			if (c == '/')
157			{
158				++i;
159
160				if (i == path.length || !(c.isalpha() || c == '_'))
161				{
162					return false;
163				}
164			}
165			else if (!(c.isalnum() || c == '_'))
166			{
167				return false;
168			}
169
170			++i;
171		}
172
173		return true;
174	}
175}
176
177}
178
179// ex:set ts=4 noet:
180