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.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 }