001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.facebookjazz;
017
018import javax.xml.bind.annotation.XmlAccessType;
019import javax.xml.bind.annotation.XmlAccessorType;
020import javax.xml.bind.annotation.XmlElement;
021import javax.xml.bind.annotation.XmlRootElement;
022
023import org.apache.commons.lang3.StringUtils;
024import org.apache.log4j.Logger;
025
026import com.restfb.types.Location;
027import com.restfb.types.NamedFacebookType;
028import com.restfb.types.Place;
029import com.restfb.types.Venue;
030
031/**
032 * Location retrieved from Facebook.
033 * 
034 * This class is used to map venue, namedfacebooktype and other zillion different kinds of facebook locations to a single object.
035 * 
036 * <h2>Conditional Elements</h2>
037 * <ul>
038 *  <li>{@value service.tut.pori.facebookjazz.Definitions#ELEMENT_CITY}</li>
039 *  <li>{@value service.tut.pori.facebookjazz.Definitions#ELEMENT_COUNTRY}</li>
040 *  <li>{@value service.tut.pori.facebookjazz.Definitions#ELEMENT_NAME}</li>
041 *  <li>{@value service.tut.pori.facebookjazz.Definitions#ELEMENT_STATE}</li>
042 * </ul>
043 * 
044 * Any of the conditional fields can be omitted, but at least one of the fields must be present.
045 * 
046 * <h3>XML Example</h3>
047 * 
048 * {@doc.restlet service="[service.tut.pori.facebookjazz.reference.Definitions#SERVICE_FBJ_REFERENCE_EXAMPLE]" method="[service.tut.pori.facebookjazz.Definitions#ELEMENT_LOCATION]" type="GET" query="" body_uri=""}
049 *
050 * @see com.restfb.types.Location
051 */
052@XmlRootElement(name=Definitions.ELEMENT_LOCATION)
053@XmlAccessorType(XmlAccessType.NONE)
054public class FacebookLocation {
055  private static final Logger LOGGER = Logger.getLogger(FacebookLocation.class);
056  private String _name = null;
057  private Location _location = null;
058  
059  /**
060   * 
061   */
062  public FacebookLocation(){
063    _location = new Location();
064  }
065  
066  /**
067   * 
068   * @param location
069   * @throws IllegalArgumentException
070   */
071  public FacebookLocation(Location location) throws IllegalArgumentException{
072    if(location == null){
073      throw new IllegalArgumentException("Invalid location.");
074    }
075    _location = location;
076  }
077  
078  /**
079   * 
080   * @param venue
081   * @return venue converted to a location
082   */
083  public static FacebookLocation getFacebookLocation(Venue venue){
084    if(venue == null){
085      return null;
086    }
087    String country = venue.getCountry();
088    String city = venue.getCity();
089    String state = venue.getState();
090    if(StringUtils.isBlank(city) && StringUtils.isBlank(country) && StringUtils.isBlank(state)){
091      LOGGER.debug("Venue contained no valid details.");
092      return null;
093    }
094    
095    FacebookLocation l = new FacebookLocation();  
096    l.setCountry(country);  
097    l.setCity(city);  
098    l.setState(state);
099    return l;
100  }
101
102  /**
103   * 
104   * @param place
105   * @return place converted to a location
106   */
107  public static FacebookLocation getFacebookLocation(Place place){
108    if(place == null){
109      return null;
110    }
111    FacebookLocation l = getFacebookLocation((NamedFacebookType)place);
112    Location location = place.getLocation();
113    boolean hadBaseDetails = true;
114    if(l == null){ // there were no namedfacebooktype details
115      if(location == null){   // and there are no location, nor any base details
116        LOGGER.debug("Place contained no valid details.");
117        return null;
118      }else{   // no base details, but there is a location
119        l = new FacebookLocation();
120        hadBaseDetails = false;
121      }       
122    }else if(location == null){   // there are no location details, but there were name
123      return l;
124    }
125
126    String country = location.getCountry();
127    String city = location.getCity();
128    String state = location.getState();
129    
130    if(!hadBaseDetails && StringUtils.isBlank(city) && StringUtils.isBlank(country) && StringUtils.isBlank(state)){
131      LOGGER.debug("Place contained no valid details.");
132      return null;
133    }
134    
135    l.setCountry(country);  
136    l.setCity(city);  
137    l.setState(state);
138    return l;
139  }
140
141  /**
142   * 
143   * @param name
144   * @return name converted to a location
145   */
146  public static FacebookLocation getFacebookLocation(String name){
147    if(StringUtils.isBlank(name)){
148      return null;
149    }else{
150      FacebookLocation l = new FacebookLocation();
151      l._name = name;
152      return l;
153    }
154  }
155
156  /**
157   * 
158   * @param type
159   * @return named type converted to a location
160   */
161  public static FacebookLocation getFacebookLocation(NamedFacebookType type){
162    if(type == null){
163      return null;
164    }
165    FacebookLocation l = new FacebookLocation();
166    l._name = type.getName();
167    if(l._name == null){
168      LOGGER.debug("Type contained no valid details.");
169      return null;
170    }else{
171      return l;
172    }
173  }
174  
175  /**
176   * @see #getName()
177   * @see #setName(String)
178   * 
179   * @return this object stripped to named facebook type or null if no valid data is present. Note that the generated object may only be partial representation of this object, depending on the object data (only name member is used)
180   */
181  public NamedFacebookType toNamedFacebookType(){
182    String name = getName();
183    if(StringUtils.isBlank(name)){
184      LOGGER.warn("No name.");
185      return null;
186    }
187    NamedFacebookType t = new NamedFacebookType();
188    t.setName(name);
189    return t;
190  }
191
192  /**
193   * @see com.restfb.types.Location#getCity()
194   * 
195   * @return city
196   * @see #setCity(String)
197   */
198  @XmlElement(name = Definitions.ELEMENT_CITY)
199  public String getCity() {
200    return _location.getCity();  
201  }
202
203  /**
204   * 
205   * @return name
206   * @see #setName(String)
207   */
208  @XmlElement(name = Definitions.ELEMENT_NAME)
209  public String getName() {
210    return _name;
211  }
212
213  /**
214   * @see com.restfb.types.Location#getState()
215   * 
216   * @return state
217   * @see #setState(String)
218   */
219  @XmlElement(name = Definitions.ELEMENT_STATE)
220  public String getState() {
221    return _location.getState();
222  }
223
224  /**
225   * @see com.restfb.types.Location#getCountry()
226   * 
227   * @return country
228   * @see #setCountry(String)
229   */
230  @XmlElement(name = Definitions.ELEMENT_COUNTRY)
231  public String getCountry() {
232    return _location.getCountry(); 
233  }
234
235  /**
236   * @param name the name to set
237   * @see #getName()
238   */
239  public void setName(String name) {
240    _name = name;
241  }
242
243  /**
244   * @param city
245   * @see com.restfb.types.Location#setCity(java.lang.String)
246   * @see #getCity()
247   */
248  public void setCity(String city) {
249    _location.setCity(city);
250  }
251
252  /**
253   * @param country
254   * @see com.restfb.types.Location#setCountry(java.lang.String)
255   * @see #getCountry()
256   */
257  public void setCountry(String country) {
258    _location.setCountry(country);
259  }
260
261  /**
262   * @param state
263   * @see com.restfb.types.Location#setState(java.lang.String)
264   * @see #getState()
265   */
266  public void setState(String state) {
267    _location.setState(state);
268  }
269
270  /**
271   * @see #setCountry(String)
272   * @see #getCountry()
273   * @see #getState()
274   * @see #setState(String)
275   * @see #getState()
276   * @see #setCity(String)
277   * @return this object stripped to place. Note that the generated object may only be partial representation of this object, depending on the object data (only country, city and state members are used)
278   */
279  public Place toPlace() {
280    Place p = new Place();
281    p.setLocation(_location);
282    return p;
283  }
284
285  /**
286   * @see #setCountry(String)
287   * @see #getCountry()
288   * @see #getState()
289   * @see #setState(String)
290   * @see #getState()
291   * @see #setCity(String)
292   * @return this object stripped to Venue or null if no valid data. Note that the generated object may only be partial representation of this object, depending on the object data (only country, city and state members are used)
293   */
294  public Venue toVenue() {
295    String country = getCountry();
296    String city = getCity();
297    String state = getState();
298    if(StringUtils.isBlank(city) && StringUtils.isBlank(country) && StringUtils.isBlank(state)){
299      LOGGER.debug("No country, city or state.");
300      return null;
301    }
302    
303    Venue v = new Venue();
304    v.setCity(city);
305    v.setCountry(country);
306    v.setState(state);
307    return v;
308  }
309}