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.contentanalysis; 017 018import javax.xml.bind.annotation.XmlAccessType; 019import javax.xml.bind.annotation.XmlAccessorType; 020import javax.xml.bind.annotation.XmlElement; 021import javax.xml.bind.annotation.XmlEnum; 022import javax.xml.bind.annotation.XmlEnumValue; 023import javax.xml.bind.annotation.XmlRootElement; 024 025import org.apache.commons.lang3.StringUtils; 026 027/** 028 * Defines a visual shape used in combination with a media object. 029 * 030 * <h3>XML Example</h3> 031 * 032 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_VISUAL_SHAPE]" type="GET" query="" body_uri=""} 033 * 034 */ 035@XmlRootElement(name=Definitions.ELEMENT_VISUAL_SHAPE) 036@XmlAccessorType(XmlAccessType.NONE) 037public class VisualShape { 038 private static final String VISUALSHAPETYPE_CIRCLE = "CIRCLE"; 039 private static final String VISUALSHAPETYPE_POLYGON = "POLYGON"; 040 private static final String VISUALSHAPETYPE_RECTANGLE = "RECTANGLE"; 041 private static final String VISUALSHAPETYPE_TRIANGLE = "TRIANGLE"; 042 @XmlElement(name = Definitions.ELEMENT_VISUAL_SHAPE_TYPE) 043 private VisualShapeType _type = null; 044 @XmlElement(name = Definitions.ELEMENT_VALUE) 045 private String _value = null; 046 047 /** 048 * Type of the shape object. 049 */ 050 @XmlEnum 051 public enum VisualShapeType{ 052 /** Rectangle bounding box. Valid value format is: "topLeftX,topLeftY,bottomRightX,bottomRightY", where all values are positive integers detonating pixel positions in the photo. */ 053 @XmlEnumValue(value=VISUALSHAPETYPE_RECTANGLE) 054 RECTANGLE(1), 055 /** Triangle bounding area. Valid value format is: "topX,topY,bottomLeftX,bottomLeftY,bottomRightX,bottomRightY", where all values are positive integers detonating pixel positions in the photo. */ 056 @XmlEnumValue(value=VISUALSHAPETYPE_TRIANGLE) 057 TRIANGLE(2), 058 /** Cricle bounding area. Valid value format is: "centerX,centerY,radius", where all values are positive integers detonating pixel positions in the photo. */ 059 @XmlEnumValue(value=VISUALSHAPETYPE_CIRCLE) 060 CIRCLE(3), 061 /** Polygon bounding area. Valid value format is: "1X,1Y,2X,2Y...nX,nY", where all values are positive integers detonating pixel positions in the photo. There should be at least 3 coordinates for a valid polygon, though it is recommended to use {@link service.tut.pori.contentanalysis.VisualShape.VisualShapeType#TRIANGLE} and {@link service.tut.pori.contentanalysis.VisualShape.VisualShapeType#RECTANGLE} for simpler objects.*/ 062 @XmlEnumValue(value=VISUALSHAPETYPE_POLYGON) 063 POLYGON(4); 064 065 private int _shapeType; 066 067 /** 068 * 069 * @param shapeType 070 */ 071 private VisualShapeType(int shapeType){ 072 _shapeType = shapeType; 073 } 074 075 /** 076 * 077 * @return the type id 078 */ 079 public final int toShapeTypeId(){ 080 return _shapeType; 081 } 082 083 /** 084 * 085 * @param shapeType 086 * @return the passed value as shape type 087 * @throws IllegalArgumentException on bad input 088 */ 089 public static VisualShapeType fromShapeTypeId(int shapeType) throws IllegalArgumentException{ 090 for(VisualShapeType e : VisualShapeType.values()){ 091 if(e._shapeType == shapeType){ 092 return e; 093 } 094 } 095 throw new IllegalArgumentException("Bad "+VisualShapeType.class.toString()+" : "+shapeType); 096 } 097 } // enum VisualShapeType 098 099 100 /** 101 * 102 * @param type 103 * @param value 104 * 105 */ 106 public VisualShape(VisualShapeType type, String value){ 107 _type = type; 108 _value = value; 109 } 110 111 /** 112 * 113 * @return value for the shape. The value differs per shape type. 114 * @see #setValue(String) 115 * @see service.tut.pori.contentanalysis.VisualShape.VisualShapeType 116 */ 117 public String getValue() { 118 return _value; 119 } 120 121 /** 122 * 123 * @param value 124 * @see #getValue() 125 */ 126 public void setValue(String value) { 127 _value = value; 128 } 129 130 /** 131 * 132 * @return type 133 * @see #setVisualShapeType(service.tut.pori.contentanalysis.VisualShape.VisualShapeType) 134 */ 135 public VisualShapeType getVisualShapeType() { 136 return _type; 137 } 138 139 /** 140 * 141 * @param type 142 * @see #getVisualShapeType() 143 */ 144 public void setVisualShapeType(VisualShapeType type) { 145 _type = type; 146 } 147 148 /** 149 * for serialization 150 */ 151 protected VisualShape(){ 152 // nothing needed 153 } 154 155 /** 156 * 157 * @param shape can be null 158 * @return true if the passed type is valid 159 */ 160 public static boolean isValid(VisualShape shape){ 161 if(shape == null){ 162 return false; 163 }else{ 164 return shape.isValid(); 165 } 166 } 167 168 /** 169 * use the static, only for sub-classing 170 * @return true if the shape is valid 171 */ 172 protected boolean isValid(){ 173 if(StringUtils.isBlank(_value) || _type == null){ 174 return false; 175 }else{ 176 return true; 177 } 178 } 179 180 /** 181 * 182 * @param shape 183 * @return the value or null if none or the given shape was null 184 */ 185 public static String getValue(VisualShape shape){ 186 return (shape == null ? null : shape.getValue()); 187 } 188 189 /** 190 * Sets the given value to the given Shape. If shape is null, new shape will be returned (with the value). 191 * If value is blank and the given shape is null, null will be returned. 192 * 193 * @param shape can be null 194 * @param value 195 * @return the passed shape, new object or null 196 */ 197 public static VisualShape setValue(VisualShape shape, String value){ 198 if(StringUtils.isBlank(value)){ 199 if(shape == null){ // no value, no pre-existing shape given 200 return null; 201 } 202 }else if(shape == null){ 203 shape = new VisualShape(); 204 } 205 shape.setValue(value); 206 return shape; 207 } 208 209 /** 210 * 211 * @param shape 212 * @return the shape type or null if shape was null or no type given for the shape 213 */ 214 public static Integer getVisualShapeTypeId(VisualShape shape){ 215 if(shape == null){ 216 return null; 217 } 218 VisualShapeType type = shape.getVisualShapeType(); 219 return (type == null ? null : type.toShapeTypeId()); 220 } 221 222 /** 223 * Sets the given value to the given Shape. If shape is null, new shape will be returned (with the value). 224 * 225 * @param shape can be null 226 * @param value 227 * @return the passed shape, new object or null 228 * @throws IllegalArgumentException on bad value 229 */ 230 public static VisualShape setVisualShapeTypeId(VisualShape shape, Integer value) throws IllegalArgumentException{ 231 if(value == null){ 232 throw new IllegalArgumentException("Value cannot be null."); 233 }else if(shape == null){ 234 shape = new VisualShape(); 235 } 236 shape.setVisualShapeType(VisualShapeType.fromShapeTypeId(value)); 237 return shape; 238 } 239 240 /** 241 * Classes implementing this interface will contain functionality for handling an VisualShape. 242 * 243 * Remember to annotate the implemented setter methods if you wish to use them with Solr (\@Field annotation). 244 * 245 * When implementing the methods, the static methods in VisualShapeCapable class may come handy. 246 * 247 */ 248 public interface VisualShapeSolrCapable{ 249 /** 250 * 251 * @param type 252 * @throws IllegalArgumentException on bad type value 253 * @see #getVisualShapeTypeId() 254 */ 255 public void setVisualShapeTypeId(Integer type) throws IllegalArgumentException; 256 257 /** 258 * 259 * @return shape type id 260 * @see #getVisualShapeTypeId() 261 */ 262 public Integer getVisualShapeTypeId(); 263 264 /** 265 * 266 * @param value 267 * @see #getVisualShapeValue() 268 */ 269 public void setVisualShapeValue(String value); 270 271 /** 272 * 273 * @return shape value 274 * @see #setVisualShapeValue(String) 275 */ 276 public String getVisualShapeValue(); 277 } // interface VisualShapeSolrCapable 278}