View Javadoc

1   /***
2   *
3   * The owl-s matcher software is subject to the GNU Lesser General
4   * Public License Version 2.1 (the "License"). You may not copy or use this
5   * file, in either source code or executable form, except in compliance
6   * with the License. You may obtain a copy of the License at
7   * http://www.fsf.org/licenses/lgpl.txt or http://www.opensource.org/.
8   *
9   * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied without
11  * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  * PURPOSE. See the License for the specific language governing rights and
13  * limitations under the License.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this distribution; if not, write to the
17  *
18  * Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330,
20  * Boston, MA  02111-1307 USA
21  *
22  * Copyright (C) 2003-2004
23  * TU Berlin, FG IVS
24  * Stefan Tang,
25  * Christoph Liebetruth,
26  * Michael C. Jaeger, 
27  *
28  * More information available at http://ivs.tu-berlin.de/
29  *
30  * $Id$
31  *
32  */
33  package de.tuberlin.ivs.owl.service;
34  
35  import org.jdom.input.SAXBuilder;
36  import org.jdom.*;
37  import org.jdom.xpath.*;
38  import java.util.*;
39  import de.tuberlin.ivs.owl.matching.Reasoner;
40  import java.net.URL;
41  import java.io.PrintStream;
42  import java.io.IOException;
43  import java.net.MalformedURLException;
44  import java.net.ConnectException;
45  
46  /***
47   * Parses a OWL-S service description into the representation classes
48   * of a OWL Service.
49   *
50   * @author Stefan Tang (steftang@stanford.edu), Christoph Liebetruth (christophl@voelcker.com)
51   * @version 1.1
52   */
53  public class OwlsParser 
54  {
55  
56  	/***
57  	 * Default constructor.
58  	 * @param out The stream that output information is written to.
59  	 */
60  	public OwlsParser(PrintStream out) 
61  	{
62  		outWriter = out;
63  	}
64  
65  	/***
66  	 * The service namespace.
67  	 */
68  	public static Namespace serviceNamespace = Namespace.getNamespace("http://www.daml.org/services/owl-s/1.0/Service.owl#");
69  
70  	/***
71  	 * The RDF namespace.
72  	 */
73  	public static Namespace rdfNamespace = Namespace.getNamespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
74  
75  	/***
76  	 * The profile namespace.
77  	 */
78  	public static Namespace profileNamespace = Namespace.getNamespace("http://www.daml.org/services/owl-s/1.0/Profile.owl#");
79  
80  
81  	/***
82  	 * The ID of the concept Profile as of OWL-S 1.0
83  	 */
84  	public static String profileID = "http://www.daml.org/services/owl-s/1.0/Profile.owl#Profile";
85  
86  	/***
87  	 * The stream that output information is written to.
88  	 */
89  	private PrintStream outWriter;
90  
91  
92  	/***
93  	 * Searches the main Xml-File for a service:Service tag and returns its rdfID as a parser entry point
94  	 * @param path The uri to the main xml
95  	 * @return a service rdfID or null if not found
96  	 */
97  	private String GetServiceID( URL path )
98  	{
99  		try
100 		{
101 			SAXBuilder builder = new SAXBuilder();
102 			Document doc = null;
103 			doc = builder.build( path );
104 			Element root = doc.getRootElement();
105 			XPath xpath = XPath.newInstance( "//service:Service" );
106 			xpath.addNamespace( "service", OwlsParser.serviceNamespace.getURI() );
107 			Element serviceNode = (Element) xpath.selectSingleNode( root );
108 			if ( serviceNode != null )
109 			{
110 				String id = serviceNode.getAttributeValue( "ID", OwlsParser.rdfNamespace );
111 				return( id );
112 			}
113 			return( null );
114 		}
115 		catch (Exception e)
116 		{
117 			return( null );
118 		}
119 	}
120 
121 
122 	/***
123 	 * Parses a OWL-S service descriptions.
124 	 * @param path The URL of the OWL-S file. Note that this file has
125 	 * to be the organizational entry point of the service descriptions (i.e. the
126 	 * root file that contains the <service> tag elements).
127 	 * @param reasoner An instance of the reasoner that represents the knowledge
128 	 * base.
129 	 * @return The parsed service.
130 	 */
131 	public Service parse(URL path, Reasoner reasoner) throws OwlsParseException 
132 	{
133 		Service service = new Service();
134 		try
135 		{
136 			reasoner.loadOwlFile( path );
137 		}
138 		catch (java.net.ConnectException ce)
139 		{
140 			throw new OwlsParseException("A remote OWL file could not be opened.\n." +
141 				ce.getMessage());
142 		}
143 		String serviceID = this.GetServiceID( path );
144 		if ( serviceID == null )
145 		{
146 			throw new OwlsParseException("Could not find any service ID. Please make sure at least one\n" +
147 				"<service:Service> element is present and has corresponding namespace\n" +
148 				serviceNamespace.getURI());
149 		}
150 
151 		// read out service
152 		service.setID( serviceID );
153 
154 		List profiles = reasoner.GetPresentedProfileIDs( service.getID() );
155 		if (profiles==null) 
156 		{
157 			throw new OwlsParseException("Could not find any profile. Please make sure at least one\n" +
158 				"<service:presents> element is present and has corresponding namespace\n" +
159 				serviceNamespace.getURI());
160 		}
161 
162 		Iterator iter = profiles.iterator();
163 		while(iter.hasNext()) 
164 		{
165 			String profileResourceID = (String) iter.next();
166 			String profilepath = profileResourceID.substring( 0, profileResourceID.lastIndexOf( "#" ) );
167 			String profileID = profileResourceID.substring( profileResourceID.lastIndexOf( "#" ) + 1 );
168 			Profile profile = this.parseProfile( profileID, profileResourceID, reasoner );
169 			profile.setService( service );
170 			service.addProfile( profile );
171 		}
172 		return( service );
173 	}
174 
175 	/***
176 	 * Parses a OWL-S profile.
177 	 * @param profileID The ID of the profile to parse, as a OWL file
178 	 * can contain several profiles.
179 	 * @param profileResourceID The ID of the profile to parse (including namespace uri) for querying
180 	 * the reasoner
181 	 * @param reasoner An instance of the reasoner that represents the knowledge
182 	 * base.
183 	 * @return a parsed profile including inputs, outputs, preconditions, effects and actors (contact information)
184 	 */
185 	private Profile parseProfile( String profileID, String profileResourceID, Reasoner reasoner ) throws OwlsParseException
186 	{
187 		Profile profile = new Profile();
188 		writeLog("Parsing profile " + profileID);
189 
190 		profile.setID( profileID );
191 		profile.setTextDescription( reasoner.GetProfileTextDescription( profileResourceID ) );
192 		profile.setServiceName( reasoner.GetProfileServiceName( profileResourceID ) );
193 		profile.setClassName( reasoner.GetRdfType( profileResourceID ) );
194 
195 		List contacts = reasoner.GetProfileContactInformationIDs( profileResourceID );
196 		Iterator contactIter = contacts.iterator();
197 		while ( contactIter.hasNext() )
198 		{
199 			String contactID = (String) contactIter.next();
200 			Actor actor = this.ParseActor( contactID, reasoner );
201 			profile.addContactInformation( actor );
202 		}
203 
204 		List inputs = reasoner.GetProfileInputIDs( profileResourceID );
205 		Iterator inputIter = inputs.iterator();
206 		while ( inputIter.hasNext() )
207 		{
208 			String rdfID = (String) inputIter.next();
209 			Input input = new Input();
210 			String rdfType = reasoner.GetRdfType( rdfID );
211 			input.setPropertyName( rdfType.substring( rdfType.lastIndexOf( "#" ) + 1 ) );
212 			input.setRefersTo( rdfID );
213 			input.setRestrictedTo( reasoner.getPropertyType( input.getRefersTo() ) );
214 			profile.addInput( input );
215 
216 		}
217 
218 		List outputs = reasoner.GetProfileOutputIDs( profileResourceID );
219 		Iterator outputIter = outputs.iterator();
220 		while ( outputIter.hasNext() )
221 		{
222 			String rdfID = (String) outputIter.next();
223 			String rdfType = reasoner.GetRdfType( rdfID );
224 			Output output = new Output();
225 			output.setPropertyName( rdfType.substring( rdfType.lastIndexOf( "#" ) + 1 ) );
226 			output.setRefersTo( rdfID );
227 			output.setRestrictedTo( reasoner.getPropertyType( output.getRefersTo() ) );
228 			profile.addOutput(output);
229 		}
230 
231 		List preconditions = reasoner.GetProfilePreconditionIDs( profileResourceID );
232 		Iterator preconditionIter = preconditions.iterator();
233 		while ( preconditionIter.hasNext() )
234 		{
235 			String rdfID = (String) preconditionIter.next();
236 			String rdfType = reasoner.GetRdfType( rdfID );
237 			Output output = new Output();
238 			output.setPropertyName( rdfType.substring( rdfType.lastIndexOf( "#" ) + 1 ) );
239 			output.setRefersTo( rdfID );
240 			output.setRestrictedTo( reasoner.getPropertyType( output.getRefersTo() ) );
241 			profile.addOutput(output);
242 		}
243 					
244 		List effects = reasoner.GetProfileEffectIDs( profileResourceID );
245 		Iterator effectIter = effects.iterator();
246 		while ( effectIter.hasNext() )
247 		{
248 			String rdfID = (String) effectIter.next();
249 			String rdfType = reasoner.GetRdfType( rdfID );
250 			Effect effect = new Effect();
251 			effect.setPropertyName( rdfType.substring( rdfType.lastIndexOf( "#" ) + 1 ) );
252 			effect.setRefersTo( rdfID );
253 			effect.setRestrictedTo( reasoner.getPropertyType( effect.getRefersTo() ) );
254 			profile.addEffect( effect );
255 		}
256 
257 		return( profile );
258 	}
259 
260 
261 
262 
263 
264 	/***
265 	 * Parses an actor class.
266 	 * @param actorResourceID the rdfResourceID of the actor including namespace uri for querying the reasoner
267 	 * @param reasoner reasoner.
268 	 * @return The parsed Actor.
269 	 */
270 	private Actor ParseActor( String actorResourceID, Reasoner reasoner )
271 	{
272 		Actor actor = new Actor();
273 		String actorID = actorResourceID.substring( actorResourceID.lastIndexOf( "#" ) + 1 );
274 		actor.setID( actorID );
275 		actor.setName( reasoner.GetActorName( actorResourceID ) );
276 		actor.setTitle( reasoner.GetActorTitle( actorResourceID ) );
277 		actor.setPhone( reasoner.GetActorPhone( actorResourceID ) );
278 		actor.setFax( reasoner.GetActorFax( actorResourceID ) );
279 		actor.setEmail( reasoner.GetActorEMail( actorResourceID ) );
280 		actor.setPhysicalAddress( reasoner.GetActorPhysicalAddress( actorResourceID ) );
281 		actor.setWebURL( reasoner.GetActorWebUrl( actorResourceID ) );
282 		return( actor );
283 	}
284 
285 
286 	/***
287 	 * Writes a message to the output stream if the stream is initialized.
288 	 * @param message The message to be written.
289 	 */
290 	private void writeLog( String message )
291 	{
292 		if ( outWriter != null )
293 		{
294 			outWriter.println( message );
295 		}
296 	}
297 }