1265bc2933ddb18f3c0e12cdce91cb40e0dc01a6
[utils] / crawler / basic / src / org / wamblee / crawler / impl / PageImpl.java
1 /*
2  * Copyright 2005 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.wamblee.crawler.impl;
18
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.commons.httpclient.NameValuePair;
25 import org.dom4j.DocumentHelper;
26 import org.dom4j.Element;
27 import org.dom4j.XPath;
28 import org.wamblee.crawler.Action;
29 import org.wamblee.crawler.Crawler;
30 import org.wamblee.crawler.Page;
31 import org.wamblee.crawler.PageType;
32
33 /**
34  * Page implementation.
35  */
36 public class PageImpl implements Page {
37
38     private static final String ELEM_NAME = "action";
39
40     private static final String ATT_NAME = "name";
41
42     private static final String ATT_HREF = "reference";
43
44     private static final String ATT_TYPE = "type";
45     
46     private static final String ELEM_PARAM = "param"; 
47     
48     private static final String ATT_VALUE = "value";
49
50     private String _href; 
51     
52     private Crawler _crawler;
53
54     private Element _content;
55
56     private Action[] _actions;
57
58     /**
59      * Constructs a page.
60      * 
61      * @param aContent
62      */
63     public PageImpl(String aHref, Crawler aCrawler, Element aContent) {
64         _href = aHref;
65         _crawler = aCrawler;
66         _content = aContent;
67         _actions = computeActions();
68     }
69
70     /*
71      * (non-Javadoc)
72      * 
73      * @see org.wamblee.crawler.Page#getLinkNames()
74      */
75     private Action[] computeActions() {
76         XPath xpath = DocumentHelper.createXPath(ELEM_NAME);
77         List<Element> results = (List<Element>) xpath.selectNodes(_content);
78         List<Action> names = new ArrayList<Action>();
79         for (Element elem : results) {
80             String name = elem.attributeValue(ATT_NAME);
81             String href = elem.attributeValue(ATT_HREF);
82             String type = elem.attributeValue(ATT_TYPE);
83             NameValuePair[] params = getMandatoryParameters(elem);
84             href = absolutizeHref(_href, href); 
85             if (type == null) {
86                 names.add(new ActionImpl(_crawler, elem, name, href, params));
87             } else {
88                 names.add(new ActionImpl(_crawler, elem, name, href,
89                         new PageType(type), params));
90             }
91         }
92         return names.toArray(new Action[0]);
93     }
94     
95     /**
96      * Absolutize the hyperlink 
97      * @param aPageHref Absolute page reference.
98      * @param aLinkHref Possibly relative link reference.
99      * @return Absolute hyperlink. 
100      */
101     private String absolutizeHref(String aPageHref, String aLinkHref) {
102         
103         try {
104             URL pageUrl = new URL(aPageHref);
105             URL newUrl = new URL(pageUrl, aLinkHref); 
106             return newUrl.toString(); // TODO need to use URL instead of String throughout the code. 
107         } catch (MalformedURLException e) {
108             throw new RuntimeException("Malformed URL", e); 
109         }
110     }
111
112     private NameValuePair[] getMandatoryParameters(Element aAction) {
113         List<NameValuePair> result = new ArrayList<NameValuePair>();
114         for (Element param: (List<Element>)aAction.elements(ELEM_PARAM)) { 
115             String name = param.attributeValue(ATT_NAME); 
116             String value = param.attributeValue(ATT_VALUE); 
117             result.add(new NameValuePair(name, value));
118         }
119         return result.toArray(new NameValuePair[0]);
120     }
121
122     /*
123      * (non-Javadoc)
124      * 
125      * @see org.wamblee.crawler.Page#getContent()
126      */
127     public Element getContent() {
128         return _content;
129     }
130
131     /*
132      * (non-Javadoc)
133      * 
134      * @see org.wamblee.crawler.Page#getActions()
135      */
136     public Action[] getActions() {
137         return _actions;
138     }
139
140     /*
141      * (non-Javadoc)
142      * 
143      * @see org.wamblee.crawler.Page#getAction(java.lang.String)
144      */
145     public Action getAction(String aName) {
146         List<Action> results = new ArrayList<Action>();
147         for (Action action : _actions) {
148             if (action.getName().equals(aName)) {
149                 results.add(action);
150             }
151         }
152         if (results.size() == 0) {
153             return null;
154         }
155         if (results.size() > 1) {
156             throw new RuntimeException("Duplicate action '" + aName + "'");
157         }
158         return results.get(0);
159     }
160 }