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.matching;
34
35 import de.tuberlin.ivs.owl.service.*;
36 import de.tuberlin.ivs.owl.matching.config.*;
37 import java.util.Vector;
38 import java.io.PrintStream;
39 import java.net.URL;
40
41 /***
42 * Base class of the matching algorithm.
43 *
44 * @author Stefan Tang (steftang@stanford.edu), Christoph Liebetruth (christophl@voelcker.com)
45 * @version 1.1
46 */
47 public class MatchingAlgorithm {
48
49 /***
50 * A list of all loaded plug-ins.
51 */
52 private Vector userDefinedPlugIns = null;
53
54 /***
55 * The configuration for the matching algorithm.
56 */
57 private Configuration config = null;
58
59 /***
60 * The instance of the reasoner class that will hold all ontology
61 * information for one matching cycle and that provides functionality
62 * for querying the knowledge base.
63 */
64 private Reasoner reasoner;
65
66 /***
67 * The output stream that output information is written to.
68 */
69 private PrintStream outWriter;
70
71 /***
72 * Default constructor. Will read the configuration file and then load
73 * all plug-ins specified in the configuration.
74 * @param out The out stream that output information will be written to.
75 */
76 public MatchingAlgorithm(PrintStream out) throws ConfigurationException, PlugInLoadException {
77 config = ConfigurationReader.readConfiguation();
78 loadUserDefinedPlugIns();
79 outWriter = out;
80 reasoner = new Reasoner(outWriter);
81 }
82
83 /***
84 * Loads all specified plug-ins from the config file.
85 */
86 private void loadUserDefinedPlugIns() throws PlugInLoadException {
87 if (config.getPlugIns()!=null) {
88 userDefinedPlugIns = new Vector();
89 for (int i=0; i<config.getPlugIns().size(); i++) {
90 PlugInConfiguration plugIn = (PlugInConfiguration)config.getPlugIns().elementAt(i);
91 try {
92 Class classDef = Class.forName(plugIn.getClassName());
93 UserPlugIn userMatch = (UserPlugIn)classDef.newInstance();
94 userDefinedPlugIns.addElement(userMatch);
95 } catch (ClassNotFoundException cnfe) {
96 throw new PlugInLoadException("Plug-in " + plugIn.getClassName() +
97 " not found.\n" + cnfe.getMessage());
98 } catch (IllegalAccessException iae) {
99 throw new PlugInLoadException("Plug-in " + plugIn.getClassName() +
100 " could not be accessed.\n" + iae.getMessage());
101 } catch (InstantiationException ie) {
102 throw new PlugInLoadException("Plug-in " + plugIn.getClassName() +
103 " could not be instantiated.\n" + ie.getMessage());
104 }
105 }
106 }
107 }
108
109 /***
110 * Parses a OWL-S service description and returns all IDs of the profiles
111 * that belong to this service.
112 * @param servicePath The path to this service.
113 * @return A vector containing strings of IDs for all profiles.
114 * @throws OwlsParseException Thrown when an error occured while parsing the
115 * OWL-S description.
116 */
117 public Vector getProfileIDsForService(URL serviceURL) throws OwlsParseException {
118 OwlsParser parser = new OwlsParser(outWriter);
119 Reasoner tempReasoner = new Reasoner(outWriter);
120 Service service = parser.parse(serviceURL,tempReasoner);
121 return service.getProfileIDs();
122 }
123
124 /***
125 * The matching algorithm. Takes the path to the requested service and
126 * the advertised service and calculates the corresponding matching result.
127 * As a service can have multiple profiles, also the corresponding profile
128 * ID has to be specified. Use the method getProfileIDsForService to obtain
129 * all profile IDs if not known in advance and then call this method for
130 * all or a specific profile ID.
131 *
132 * @param reqServiceURL The URL for the requested service.
133 * @param reqProfileID The ID of the profile of the requested service that
134 * will be matched. If null, the first profile of the service will be matched.
135 * @param advServiceURL The URL for the advertised service.
136 * @param advProfileID The ID of the profile of the advertised service that
137 * will be matched. If null, the first profile of the service will be matched.
138 * @param minProfileDegree The minimal expected matching degree for profile
139 * matching.
140 * @param minInputDegree The minimal expected matching degree for input
141 * parameter matching.
142 * @param minOutputDegree The minimal expected matching degree for output
143 * parameter matching.
144 * @return True if the two profiles match based on the minimal expected
145 * degrees, false if at least one partial matching fails.
146 * @throws OwlsParseException Is thrown when an error occurs while parsing
147 * the services.
148 */
149 public boolean match(URL reqServiceURL, String reqProfileID,
150 URL advServiceURL, String advProfileID,
151 int minProfileDegree, int minInputDegree, int minOutputDegree)
152 throws OwlsParseException {
153
154 try {
155 Options.extendedResult = new ExtendedMatchingResult();
156 Options.extendedResult.setMinimalInputDegree(minInputDegree);
157 Options.extendedResult.setMinimalOutputDegree(minOutputDegree);
158 Options.extendedResult.setMinimalProfileDegree(minProfileDegree);
159 OwlsParser parser = new OwlsParser(outWriter);
160 Service reqService = parser.parse(reqServiceURL, reasoner);
161 Service advService = parser.parse(advServiceURL, reasoner);
162 Profile reqProfile = null;
163 if (reqProfileID == null) {
164 reqProfile = (Profile) reqService.getProfiles().elementAt(0);
165 }
166 else {
167 reqProfile = reqService.getProfileByID(reqProfileID);
168 if (reqProfile == null) {
169 throw new OwlsParseException(
170 "Could not find the specified profile of the " +
171 "requested service: " + reqProfileID);
172 }
173
174 }
175 Profile advProfile = null;
176 if (advProfileID == null) {
177 advProfile = (Profile) advService.getProfiles().elementAt(0);
178 }
179 else {
180 advProfile = advService.getProfileByID(advProfileID);
181 if (advProfile == null) {
182 throw new OwlsParseException(
183 "Could not find the specified profile of the " +
184 "advertised service: " + advProfileID);
185 }
186 }
187 Options.extendedResult.setFinalMatchingResult(matchingAlgorithm(reqProfile,
188 advProfile,minProfileDegree, minInputDegree, minOutputDegree));
189 return Options.extendedResult.getFinalMatchingResult();
190 } catch (Exception e) {
191 throw new OwlsParseException(e.getMessage() + "\n" + e.toString());
192 }
193 }
194
195 /***
196 * The actual matching algorithm. Is called by the match method after the
197 * services are parsed and the knowlegde bass is initialized.
198 * @param reqServiceProfile The profile of the requested service.
199 * @param advServiceProfile The profile of the advertised service.
200 * @param minProfileDegree The minimal expected matching degree for profile
201 * matching.
202 * @param minInputDegree The minimal expected matching degree for input
203 * parameter matching.
204 * @param minOutputDegree The minimal expected matching degree for output
205 * parameter matching.
206 * @return True if the profiles match, false otherwise.
207 */
208 private boolean matchingAlgorithm(Profile reqServiceProfile, Profile advServiceProfile,
209 int minProfileDegree, int minInputDegree, int minOutputDegree) {
210
211 ProfileMatching profileMatching = new ProfileMatching(outWriter);
212 InputParameterMatching inputMatching = new InputParameterMatching(outWriter);
213 OutputParameterMatching outputMatching = new OutputParameterMatching(outWriter);
214 UserDefinedMatching userMatching = new UserDefinedMatching();
215 writeLog("Matching profiles.");
216 int profile = profileMatching.match(reqServiceProfile.getClassName(),
217 advServiceProfile.getClassName(), reasoner);
218 Options.extendedResult.setProfileMatching(profile);
219 writeLog("Matching inputs.");
220 int inputs = inputMatching.match(reqServiceProfile.getInputs(),
221 advServiceProfile.getInputs(), reasoner);
222 Options.extendedResult.setInputMatching(inputs);
223 writeLog("Matching outputs");
224 int outputs = outputMatching.match(reqServiceProfile.getOutputs(),advServiceProfile.getOutputs(),
225 reasoner);
226 Options.extendedResult.setOutputMatching(outputs);
227 writeLog("Matching active plug-ins");
228 boolean user = userMatching.match(userDefinedPlugIns, config, reqServiceProfile.getService(),
229 advServiceProfile.getService(), reasoner);
230
231 if (!user) {
232 return false;
233 }
234 return (minProfileDegree<=profile && minInputDegree<=inputs && minOutputDegree<=outputs);
235 }
236
237 /***
238 * Returns the extended matching result. This method will return an
239 * extended description of the matching procedureafter the match function
240 * has been called. Will return null if this method is called before the
241 * execution of match.
242 * @return
243 */
244 public ExtendedMatchingResult getExtendedMatchingResult() {
245 return Options.extendedResult;
246 }
247
248 /***
249 * Writes a message to the output stream if the stream is initialized.
250 * @param message The message to be written.
251 */
252 private void writeLog(String message) {
253 if (outWriter!=null) {
254 outWriter.println(message);
255 }
256 }
257
258 }