e27c1c65feeb4ad13384a69eef14b6d2c8eeb2f7
[utils] / crawler / basic / src / main / java / 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  * @author Erik Brakkee
37  */
38 public class PageImpl implements Page {
39
40     private static final String ELEM_NAME = "action";
41
42     private static final String ATT_NAME = "name";
43
44     private static final String ATT_HREF = "reference";
45
46     private static final String ATT_TYPE = "type";
47     
48     private static final String ELEM_PARAM = "param"; 
49     
50     private static final String ATT_VALUE = "value";
51
52     private String _href; 
53     
54     private Crawler _crawler;
55
56     private Element _content;
57
58     private Action[] _actions;
59
60     /**
61      * Constructs a page.
62      * 
63      * @param aContent
64      */
65     public PageImpl(String aHref, Crawler aCrawler, Element aContent) {
66         _href = aHref;
67         _crawler = aCrawler;
68         _content = aContent;
69         _actions = computeActions();
70     }
71
72     /*
73      * (non-Javadoc)
74      * 
75      * @see org.wamblee.crawler.Page#getLinkNames()
76      */
77     private Action[] computeActions() {
78         XPath xpath = DocumentHelper.createXPath(ELEM_NAME);
79         List<Element> results = (List<Element>) xpath.selectNodes(_content);
80         List<Action> names = new ArrayList<Action>();
81         for (Element elem : results) {
82             String name = elem.attributeValue(ATT_NAME);
83             String href = elem.attributeValue(ATT_HREF);
84             String type = elem.attributeValue(ATT_TYPE);
85             NameValuePair[] params = getMandatoryParameters(elem);
86             href = absolutizeHref(_href, href); 
87             if (type == null) {
88                 names.add(new ActionImpl(_crawler, elem, name, href, params));
89             } else {
90                 names.add(new ActionImpl(_crawler, elem, name, href,
91                         new PageType(type), params));
92             }
93         }
94         return names.toArray(new Action[0]);
95     }
96     
97     /**
98      * Absolutize the hyperlink 
99      * @param aPageHref Absolute page reference.
100      * @param aLinkHref Possibly relative link reference.
101      * @return Absolute hyperlink. 
102      */
103     private String absolutizeHref(String aPageHref, String aLinkHref) {
104         
105         try {
106             URL pageUrl = new URL(aPageHref);
107             URL newUrl = new URL(pageUrl, aLinkHref); 
108             return newUrl.toString(); // TODO need to use URL instead of String throughout the code. 
109         } catch (MalformedURLException e) {
110             throw new RuntimeException("Malformed URL", e); 
111         }
112     }
113
114     private NameValuePair[] getMandatoryParameters(Element aAction) {
115         List<NameValuePair> result = new ArrayList<NameValuePair>();
116         for (Element param: (List<Element>)aAction.elements(ELEM_PARAM)) { 
117             String name = param.attributeValue(ATT_NAME); 
118             String value = param.attributeValue(ATT_VALUE); 
119             result.add(new NameValuePair(name, value));
120         }
121         return result.toArray(new NameValuePair[0]);
122     }
123
124     /*
125      * (non-Javadoc)
126      * 
127      * @see org.wamblee.crawler.Page#getContent()
128      */
129     public Element getContent() {
130         return _content;
131     }
132
133     /*
134      * (non-Javadoc)
135      * 
136      * @see org.wamblee.crawler.Page#getActions()
137      */
138     public Action[] getActions() {
139         return _actions;
140     }
141
142     /*
143      * (non-Javadoc)
144      * 
145      * @see org.wamblee.crawler.Page#getAction(java.lang.String)
146      */
147     public Action getAction(String aName) {
148         List<Action> results = new ArrayList<Action>();
149         for (Action action : _actions) {
150             if (action.getName().equals(aName)) {
151                 results.add(action);
152             }
153         }
154         if (results.size() == 0) {
155             return null;
156         }
157         if (results.size() > 1) {
158             throw new RuntimeException("Duplicate action '" + aName + "'");
159         }
160         return results.get(0);
161     }
162 }