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 java.util.Date; 019import java.util.EnumSet; 020import java.util.List; 021 022import javax.xml.bind.annotation.XmlAccessType; 023import javax.xml.bind.annotation.XmlAccessorType; 024import javax.xml.bind.annotation.XmlElement; 025import javax.xml.bind.annotation.XmlEnum; 026import javax.xml.bind.annotation.XmlEnumValue; 027import javax.xml.bind.annotation.XmlRootElement; 028 029import org.apache.commons.lang3.StringUtils; 030import org.apache.log4j.Logger; 031import org.apache.solr.client.solrj.beans.Field; 032 033import service.tut.pori.contentanalysis.CAContentCore.ServiceType; 034import service.tut.pori.contentanalysis.CAContentCore.Visibility; 035import service.tut.pori.contentanalysis.video.TimecodeList; 036import core.tut.pori.dao.SolrDAO; 037import core.tut.pori.http.parameters.DataGroups; 038import core.tut.pori.users.UserIdentity; 039import core.tut.pori.utils.MediaUrlValidator.MediaType; 040 041/** 042 * <p>A class that defines a single media object. All media objects are by default of type {@link core.tut.pori.utils.MediaUrlValidator.MediaType#UNKNOWN}}.</p> 043 * 044 * <p>Note: when using this class, never pass partial objects to database methods, missing information 045 * (e.g. value == null) may be assumed to be marked as "deleted", and will be removed from the database.</p> 046 * 047 * <p>Media objects are objects which were identified from the content given for analysis (e.g. from photos).</p> 048 * 049 * <p>Back-ends may only edit objects which have been created by them (checked by objectId, {@link #getObjectId()} and backendId, {@link #getBackendId()}). Back-ends may not edit objects which have been confirmed by the user.</p> 050 * 051 * <p>If a back-end wants to modify an object created by another back-end, it must generate and submit a new ({@link service.tut.pori.contentanalysis.MediaObject.ConfirmationStatus#CANDIDATE}) media object.</p> 052 * 053 * <h2>Optional Elements</h2> 054 * 055 * <ul> 056 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_BACKEND_ID}, missing if the object is not generated by a back-end.</li> 057 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_VALUE}</li> 058 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_NAME}</li> 059 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_CONFIDENCE}, missing value means that the confidence is unknown.</li> 060 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_OBJECT_ID}, may not be present on objects created by the system.</li> 061 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_MEDIA_TYPE}, if omitted it will default to {@link core.tut.pori.utils.MediaUrlValidator.MediaType#UNKNOWN} OR if object is part of a container object, such as {@link service.tut.pori.contentanalysis.Media} the container's type will be used (see {@link service.tut.pori.contentanalysis.Media#getMediaType()}).</li> 062 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_MEDIA_OBJECT_ID}, can be omitted (and is ignored) for new objects. Automatically generated by the system.</li> 063 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_RANK}, if missing, the value should be assumed to be 0 (neutral).</li> 064 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_RESULT_INFO}</li> 065 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_SERVICE_ID}, not present for objects created by user or a back-end.</li> 066 * <li>{@value service.tut.pori.contentanalysis.video.Definitions#ELEMENT_TIMECODELIST}. If timecode list is missing or is empty, the object is assumed to describe the entire content.</li> 067 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_VISUAL_SHAPE}</li> 068 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_VISIBILITY}, if missing should be assumed to be {@link service.tut.pori.contentanalysis.CAContentCore.Visibility#PRIVATE}.</li> 069 * </ul> 070 * 071 * <h3>XML Example</h3> 072 * 073 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_MEDIA_OBJECT]" type="GET" query="" body_uri=""} 074 * 075 * @see service.tut.pori.contentanalysis.VisualShape 076 */ 077@XmlRootElement(name=Definitions.ELEMENT_MEDIA_OBJECT) 078@XmlAccessorType(XmlAccessType.NONE) 079public class MediaObject implements VisualShape.VisualShapeSolrCapable { 080 private static final String CONFIRMATIONSTATUS_BACKEND_REMOVED = "BACKEND_REMOVED"; 081 private static final String CONFIRMATIONSTATUS_CANDIDATE = "CANDIDATE"; 082 private static final String CONFIRMATIONSTATUS_NO_FRIENDLY_KEYWORD = "NO_FRIENDLY_KEYWORD"; 083 private static final String CONFIRMATIONSTATUS_USER_CONFIRMED = "USER_CONFIRMED"; 084 private static final String CONFIRMATIONSTATUS_USER_REJECTED = "USER_REJECTED"; 085 private static final String MEDIAOBJECTTYPE_FACE = "FACE"; 086 private static final String MEDIAOBJECTTYPE_KEYWORD = "KEYWORD"; 087 private static final String MEDIAOBJECTTYPE_METADATA = "METADATA"; 088 private static final String MEDIAOBJECTTYPE_OBJECT = "OBJECT"; 089 private static final Logger LOGGER = Logger.getLogger(MediaObject.class); 090 @Field(Definitions.SOLR_FIELD_BACKEND_ID) 091 @XmlElement(name = Definitions.ELEMENT_BACKEND_ID) 092 private Integer _backendId = null; 093 @Field(Definitions.SOLR_FIELD_CONFIDENCE) 094 @XmlElement(name = Definitions.ELEMENT_CONFIDENCE) 095 private Double _confidence = null; 096 /** Unique, internally generated id */ 097 @Field(SolrDAO.SOLR_FIELD_ID) 098 @XmlElement(name = Definitions.ELEMENT_MEDIA_OBJECT_ID) 099 private String _mediaObjectId = null; 100 @XmlElement(name = Definitions.ELEMENT_MEDIA_TYPE) 101 private MediaType _mediaType = MediaType.UNKNOWN; 102 @Field(Definitions.SOLR_FIELD_NAME) 103 @XmlElement(name = Definitions.ELEMENT_NAME) 104 private String _name = null; 105 /** Externally generated id. Unique when used in combination with back-end id, or if back-end id is missing, with user id. */ 106 @Field(Definitions.SOLR_FIELD_CREATOR_OBJECT_ID) 107 @XmlElement(name = Definitions.ELEMENT_OBJECT_ID) 108 private String _objectId = null; 109 @Field(Definitions.SOLR_FIELD_RANK) 110 @XmlElement(name = Definitions.ELEMENT_RANK) 111 private Integer _rank = null; 112 @XmlElement(name = Definitions.ELEMENT_SERVICE_ID) 113 private ServiceType _serviceType = null; 114 @XmlElement(name = Definitions.ELEMENT_VISUAL_SHAPE) 115 private VisualShape _shape = null; 116 @XmlElement(name = Definitions.ELEMENT_STATUS) 117 private ConfirmationStatus _status = null; 118 @XmlElement(name = Definitions.ELEMENT_MEDIA_OBJECT_TYPE) 119 private MediaObjectType _type = null; 120 @Field(Definitions.SOLR_FIELD_UPDATED) 121 private Date _updated = null; 122 private UserIdentity _userId = null; 123 @Field(Definitions.SOLR_FIELD_VALUE) 124 @XmlElement(name = Definitions.ELEMENT_VALUE) 125 private String _value = null; 126 @XmlElement(name = Definitions.ELEMENT_VISIBILITY) 127 private Visibility _visibility = null; 128 @XmlElement(name = service.tut.pori.contentanalysis.video.Definitions.ELEMENT_TIMECODELIST) 129 private TimecodeList _timecodes = null; 130 131 /** 132 * The type of the media object. 133 * 134 */ 135 @XmlEnum 136 public enum MediaObjectType{ 137 /** media object containing a keyword or a tag */ 138 @XmlEnumValue(value = MEDIAOBJECTTYPE_KEYWORD) 139 KEYWORD(1), 140 /** media object containing generic name-value type metadata */ 141 @XmlEnumValue(value = MEDIAOBJECTTYPE_METADATA) 142 METADATA(2), 143 /** generic unspecified media object */ 144 @XmlEnumValue(value = MEDIAOBJECTTYPE_OBJECT) 145 OBJECT(3), 146 /** media object containing a face recognition data */ 147 @XmlEnumValue(value = MEDIAOBJECTTYPE_FACE) 148 FACE(4); 149 150 private int _value; 151 152 /** 153 * 154 * @param value 155 */ 156 private MediaObjectType(int value){ 157 _value = value; 158 } 159 160 /** 161 * 162 * @return the type as integer 163 */ 164 public int toInt(){ 165 return _value; 166 } 167 168 /** 169 * 170 * @param types 171 * @return the set of types converted to int array or null if null or empty set was passed 172 */ 173 public static int[] toIntArray(EnumSet<MediaObjectType> types){ 174 if(types == null || types.isEmpty()){ 175 LOGGER.debug("Empty set."); 176 return null; 177 } 178 int[] array = new int[types.size()]; 179 int index = 0; 180 for(MediaObjectType t : types){ 181 array[index++] = t.toInt(); 182 } 183 return array; 184 } 185 186 /** 187 * 188 * @param types 189 * @return data groups associated with the given types or null if null or empty set was passed 190 */ 191 public static DataGroups getDataGroup(EnumSet<MediaObjectType> types){ 192 if(types == null || types.isEmpty()) 193 return null; 194 DataGroups groups = new DataGroups(); 195 for(MediaObjectType type : types){ 196 switch(type){ 197 case FACE: 198 groups.addDataGroup(Definitions.DATA_GROUP_FACE); 199 break; 200 case KEYWORD: 201 groups.addDataGroup(Definitions.DATA_GROUP_KEYWORDS); 202 break; 203 case METADATA: 204 groups.addDataGroup(Definitions.DATA_GROUP_METADATA); 205 break; 206 case OBJECT: 207 groups.addDataGroup(Definitions.DATA_GROUP_OBJECT); 208 break; 209 default: 210 LOGGER.warn("Ignored unknown object type: "+type.toInt()); 211 } // switch 212 } // for 213 return groups; 214 } 215 216 /** 217 * 218 * @param value 219 * @return value converted to a type 220 * @throws IllegalArgumentException on bad value 221 */ 222 public static MediaObjectType fromInt(int value) throws IllegalArgumentException{ 223 for(MediaObjectType t : MediaObjectType.values()){ 224 if(t._value == value){ 225 return t; 226 } 227 } 228 throw new IllegalArgumentException("Bad "+MediaObjectType.class.toString()+" : "+value); 229 } 230 231 /** 232 * Allows convertion of data group string to enumerations based on the enumeration value (string/name) 233 * 234 * @param dataGroups 235 * @return set of types associated with the given data groups or null if empty or null data group was passed 236 */ 237 public static EnumSet<MediaObjectType> fromDataGroups(DataGroups dataGroups){ 238 if(DataGroups.isEmpty(dataGroups)){ 239 LOGGER.debug("Empty data group."); 240 return null; 241 } 242 243 if(DataGroups.hasDataGroup(DataGroups.DATA_GROUP_ALL, dataGroups)){ 244 return EnumSet.allOf(MediaObjectType.class); 245 } 246 247 EnumSet<MediaObjectType> results = EnumSet.noneOf(MediaObjectType.class); 248 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_KEYWORDS, dataGroups)){ 249 results.add(KEYWORD); 250 } 251 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_FACE, dataGroups)){ 252 results.add(FACE); 253 } 254 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_METADATA, dataGroups)){ 255 results.add(METADATA); 256 } 257 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_OBJECT, dataGroups)){ 258 results.add(OBJECT); 259 } 260 261 if(results.isEmpty()){ 262 return null; 263 }else{ 264 return results; 265 } 266 } 267 } // enum MediaObjectType 268 269 /** 270 * The confirmation status of the media object. 271 * 272 * 273 */ 274 @XmlEnum 275 public enum ConfirmationStatus{ 276 /** object has been automatically generated and user has not confirmed whether he/she wants it or not */ 277 @XmlEnumValue(value = CONFIRMATIONSTATUS_CANDIDATE) 278 CANDIDATE(1), 279 /** this object has been accepted by the user, it can originally be created by a back-end or by the user */ 280 @XmlEnumValue(value = CONFIRMATIONSTATUS_USER_CONFIRMED) 281 USER_CONFIRMED(2), 282 /** basically this means that user does not want the object, and it should be deleted. */ 283 @XmlEnumValue(value = CONFIRMATIONSTATUS_USER_REJECTED) 284 USER_REJECTED(3), 285 /** back-end has requested this object to be removed as not being valid, possibly because of previously inaccurate analysis results. */ 286 @XmlEnumValue(value = CONFIRMATIONSTATUS_BACKEND_REMOVED) 287 BACKEND_REMOVED(4), 288 /** special status declaring that no friendly keyword data is available */ 289 @XmlEnumValue(value = CONFIRMATIONSTATUS_NO_FRIENDLY_KEYWORD) 290 NO_FRIENDLY_KEYWORD(5); 291 292 private int _value; 293 294 /** 295 * 296 * @param value 297 */ 298 private ConfirmationStatus(int value){ 299 _value = value; 300 } 301 302 /** 303 * 304 * @return status as integer 305 */ 306 public int toInt(){ 307 return _value; 308 } 309 310 /** 311 * 312 * @param status 313 * @return the given set as an integer array or null if null or empty set was passed 314 */ 315 public static int[] toIntArray(EnumSet<ConfirmationStatus> status){ 316 if(status == null || status.isEmpty()){ 317 return null; 318 } 319 int[] array = new int[status.size()]; 320 int index = 0; 321 for(ConfirmationStatus c : status){ 322 array[index++] = c.toInt(); 323 } 324 return array; 325 } 326 327 /** 328 * 329 * @param value 330 * @return the value converted to status 331 * @throws IllegalArgumentException 332 */ 333 public static ConfirmationStatus fromInt(int value) throws IllegalArgumentException{ 334 for(ConfirmationStatus t : ConfirmationStatus.values()){ 335 if(t._value == value){ 336 return t; 337 } 338 } 339 throw new IllegalArgumentException("Bad "+ConfirmationStatus.class.toString()+" : "+value); 340 } 341 342 /** 343 * 344 * @param dataGroups 345 * @return null if datagroups is null or empty or does not contain any valid datagroups 346 * 347 */ 348 public static EnumSet<ConfirmationStatus> fromDataGroups(DataGroups dataGroups){ 349 if(dataGroups == null){ 350 return null; 351 } 352 353 if(DataGroups.hasDataGroup(DataGroups.DATA_GROUP_ALL, dataGroups)){ 354 return EnumSet.allOf(ConfirmationStatus.class); 355 } 356 357 EnumSet<ConfirmationStatus> results = EnumSet.noneOf(ConfirmationStatus.class); 358 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_BACKEND_REMOVED, dataGroups)){ 359 results.add(BACKEND_REMOVED); 360 } 361 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_CANDIDATE, dataGroups)){ 362 results.add(CANDIDATE); 363 } 364 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_USER_CONFIRMED, dataGroups)){ 365 results.add(USER_CONFIRMED); 366 } 367 if(DataGroups.hasDataGroup(Definitions.DATA_GROUP_USER_REJECTED, dataGroups)){ 368 results.add(USER_REJECTED); 369 } 370 371 if(results.isEmpty()){ 372 return null; 373 }else{ 374 return results; 375 } 376 } 377 } // enum ConfirmationStatus 378 379 /** 380 * for serialization, must be public for solr. 381 */ 382 public MediaObject(){ 383 // nothing needed 384 } 385 386 /** 387 * 388 * @param mediaType 389 * @param mediaObjectType 390 */ 391 public MediaObject(MediaType mediaType, MediaObjectType mediaObjectType){ 392 _type = mediaObjectType; 393 _mediaType = mediaType; 394 } 395 396 /** 397 * 398 * @return confidence estimate for this object, if < 1 or null, the confidence is assumed to be unknown. 399 * @see #setConfidence(Double) 400 */ 401 public Double getConfidence() { 402 return _confidence; 403 } 404 405 /** 406 * 407 * @param confidence 408 * @see #getConfidence() 409 */ 410 public void setConfidence(Double confidence) { 411 _confidence = confidence; 412 } 413 414 /** 415 * 416 * @return the owner user identity 417 * @see #setOwnerUserId(UserIdentity) 418 */ 419 public UserIdentity getOwnerUserId() { 420 return _userId; 421 } 422 423 /** 424 * 425 * @param userId 426 * @see #getOwnerUserId() 427 */ 428 public void setOwnerUserId(UserIdentity userId) { 429 _userId = userId; 430 } 431 432 /** 433 * @see #getOwnerUserId() 434 * 435 * @return owner user identity value 436 */ 437 @XmlElement(name = core.tut.pori.users.Definitions.ELEMENT_USER_ID) 438 public Long getOwnerUserIdValue() { 439 return (_userId == null ? null : _userId.getUserId()); 440 } 441 442 /** 443 * for serialization 444 * @param userId 445 * @see #setOwnerUserId(UserIdentity) 446 */ 447 @Field(Definitions.SOLR_FIELD_USER_ID) 448 private void setOwnerUserIdValue(Long userId) { 449 _userId = (userId == null ? null : new UserIdentity(userId)); 450 } 451 452 /** 453 * 454 * @return service type 455 * @see #setServiceType(service.tut.pori.contentanalysis.CAContentCore.ServiceType) 456 */ 457 public ServiceType getServiceType() { 458 return _serviceType; 459 } 460 461 /** 462 * 463 * @param serviceType 464 * @see #getServiceType() 465 */ 466 public void setServiceType(ServiceType serviceType) { 467 _serviceType = serviceType; 468 } 469 470 /** 471 * 472 * @return object value, can be same as name 473 * @see #getName() 474 * @see #setValue(String) 475 */ 476 public String getValue() { 477 return _value; 478 } 479 480 /** 481 * Generally externally generated id, unique only when used in combination with back-end id, or if back-end id is missing, with user id. 482 * 483 * @return non-unique creator specific object id 484 * @see #setObjectId(String) 485 */ 486 public String getObjectId() { 487 return _objectId; 488 } 489 490 /** 491 * 492 * @param objectId 493 * @see #getObjectId() 494 */ 495 public void setObjectId(String objectId) { 496 _objectId = objectId; 497 } 498 499 /** 500 * Internally generated, unique Id. 501 * 502 * @return DB (row) id 503 * @see #setMediaObjectId(String) 504 */ 505 public String getMediaObjectId() { 506 return _mediaObjectId; 507 } 508 509 /** 510 * 511 * @param id DB (row) id 512 * @see #getMediaObjectId() 513 */ 514 public void setMediaObjectId(String id) { 515 _mediaObjectId = id; 516 } 517 518 /** 519 * 520 * @return back-end id 521 * @see #setBackendId(Integer) 522 */ 523 public Integer getBackendId() { 524 return _backendId; 525 } 526 527 /** 528 * 529 * @param backendId 530 * @see #getBackendId() 531 */ 532 public void setBackendId(Integer backendId) { 533 _backendId = backendId; 534 } 535 536 /** 537 * 538 * @return status 539 * @see #setConfirmationStatus(ConfirmationStatus) 540 */ 541 public ConfirmationStatus getConfirmationStatus() { 542 return _status; 543 } 544 545 /** 546 * 547 * @param status 548 * @see #getConfirmationStatus() 549 */ 550 public void setConfirmationStatus(ConfirmationStatus status) { 551 _status = status; 552 } 553 554 /** 555 * for serialization 556 * 557 * @param value 558 * @see #setConfirmationStatus(ConfirmationStatus) 559 */ 560 @Field(Definitions.SOLR_FIELD_STATUS) 561 private void setConfirmationStatusValue(Integer value){ 562 _status = (value == null ? null : ConfirmationStatus.fromInt(value)); 563 } 564 565 /** 566 * @see #getConfirmationStatus() 567 * 568 * @return status value 569 */ 570 public Integer getConfirmationStatusValue(){ 571 return (_status == null ? null : _status.toInt()); 572 } 573 574 /** 575 * 576 * @return shape 577 * @see #setVisualShape(VisualShape) 578 */ 579 public VisualShape getVisualShape() { 580 return _shape; 581 } 582 583 /** 584 * 585 * @param shape 586 * @see #getVisualShape() 587 */ 588 public void setVisualShape(VisualShape shape) { 589 _shape = shape; 590 } 591 592 /** 593 * 594 * @param value 595 * @see #getValue() 596 */ 597 public void setValue(String value) { 598 _value = value; 599 } 600 601 /** 602 * 603 * @param type 604 * @see #getMediaObjectType() 605 */ 606 public void setMediaObjectType(MediaObjectType type) { 607 _type = type; 608 } 609 610 /** 611 * 612 * @return object type 613 * @see #setMediaObjectType(MediaObjectType) 614 */ 615 public MediaObjectType getMediaObjectType() { 616 return _type; 617 } 618 619 /** 620 * 621 * @param value 622 * @see #setMediaObjectType(MediaObjectType) 623 */ 624 @Field(Definitions.SOLR_FIELD_MEDIA_OBJECT_TYPE) 625 private void setMediaObjectTypeValue(Integer value) { 626 _type = (value == null ? null : MediaObjectType.fromInt(value)); 627 } 628 629 /** 630 * @see #getMediaObjectType() 631 * 632 * @return object type value 633 */ 634 public Integer getMediaObjectTypeValue() { 635 return (_type == null ? null : _type.toInt()); 636 } 637 638 /** 639 * 640 * @param serviceId 641 * @see #setServiceType(service.tut.pori.contentanalysis.CAContentCore.ServiceType) 642 */ 643 @Field(Definitions.SOLR_FIELD_SERVICE_ID) 644 private void setServiceId(Integer serviceId){ 645 _serviceType = (serviceId == null ? null : ServiceType.fromServiceId(serviceId)); 646 } 647 648 /** 649 * @see #getServiceType() 650 * 651 * @return service type id 652 */ 653 public Integer getServiceId() { 654 return (_serviceType == null ? null : _serviceType.getServiceId()); 655 } 656 657 /** 658 * 659 * @return name or short description of the object 660 * @see #setName(String) 661 */ 662 public String getName() { 663 return _name; 664 } 665 666 /** 667 * 668 * @param name 669 * @see #getName() 670 */ 671 public void setName(String name) { 672 _name = name; 673 } 674 675 /** 676 * 677 * @param object can be null 678 * @return true if the passed object is valid 679 */ 680 public static boolean isValid(MediaObject object){ 681 if(object == null){ 682 return false; 683 }else{ 684 return object.isValid(); 685 } 686 } 687 688 /** 689 * 690 * @return true if the object is valid 691 * @see #isValid(MediaObject) 692 */ 693 protected boolean isValid(){ 694 if(_objectId == null || _status == null || _type == null){ 695 if(_mediaObjectId == null){ 696 LOGGER.debug("No mediaObjectId."); 697 } 698 return false; 699 }else if(MediaObjectType.KEYWORD.equals(_type) && StringUtils.isBlank(_value) && StringUtils.isBlank(_value)){ 700 LOGGER.warn("Invalid name or value for object of type "+MediaObjectType.KEYWORD.name()); 701 return false; 702 }else if(MediaObjectType.METADATA.equals(_type) && (StringUtils.isBlank(_value) || StringUtils.isBlank(_value))){ 703 LOGGER.warn("Invalid name/value pair for object of type "+MediaObjectType.METADATA.name()); 704 return false; 705 }else if(_timecodes != null && !TimecodeList.isValid(_timecodes)){ 706 LOGGER.warn("Invalid timecode list."); 707 return false; 708 }else if(_shape != null){ 709 return VisualShape.isValid(_shape); 710 }else{ 711 return true; 712 } 713 } 714 715 /** 716 * 717 * @param visibility 718 * @see #getVisibility() 719 */ 720 public void setVisibility(Visibility visibility){ 721 _visibility = visibility; 722 } 723 724 /** 725 * 726 * @return object visibility 727 * @see #setVisibility(service.tut.pori.contentanalysis.CAContentCore.Visibility) 728 */ 729 public Visibility getVisibility(){ 730 return _visibility; 731 } 732 733 /** 734 * @see #getVisibility() 735 * 736 * @return visibility value 737 */ 738 public Integer getVisibilityValue(){ 739 return (_visibility == null ? null : _visibility.toInt()); 740 } 741 742 /** 743 * 744 * @param visibility 745 * @see #setVisibility(service.tut.pori.contentanalysis.CAContentCore.Visibility) 746 */ 747 @Field(Definitions.SOLR_FIELD_VISIBILITY) 748 private void setVisibilityValue(Integer visibility){ 749 _visibility = (visibility == null ? null : Visibility.fromInt(visibility)); 750 } 751 752 /** 753 * @return the updated 754 */ 755 public Date getUpdated() { 756 return _updated; 757 } 758 759 /** 760 * @param updated the updated to set 761 */ 762 public void setUpdated(Date updated) { 763 _updated = updated; 764 } 765 766 @Field(Definitions.SOLR_FIELD_VISUAL_SHAPE_TYPE) 767 @Override 768 public void setVisualShapeTypeId(Integer type) throws IllegalArgumentException { 769 _shape = VisualShape.setVisualShapeTypeId(_shape, type); 770 } 771 772 @Override 773 public Integer getVisualShapeTypeId() { 774 return VisualShape.getVisualShapeTypeId(_shape); 775 } 776 777 @Field(Definitions.SOLR_FIELD_VISUAL_SHAPE_VALUE) 778 @Override 779 public void setVisualShapeValue(String value) { 780 _shape = VisualShape.setValue(_shape, value); 781 } 782 783 @Override 784 public String getVisualShapeValue() { 785 return VisualShape.getValue(_shape); 786 } 787 788 /** 789 * @return the rank 790 * @see #setRank(Integer) 791 */ 792 public Integer getRank() { 793 return _rank; 794 } 795 796 /** 797 * @param rank the rank to set 798 * @see #getRank() 799 */ 800 public void setRank(Integer rank) { 801 _rank = rank; 802 } 803 804 /** 805 * @return the mediaType 806 */ 807 public MediaType getMediaType() { 808 return _mediaType; 809 } 810 811 /** 812 * @param mediaType the mediaType to set 813 */ 814 public void setMediaType(MediaType mediaType) { 815 _mediaType = mediaType; 816 } 817 818 /** 819 * for serialization 820 * 821 * @param value 822 * @see #setMediaType(core.tut.pori.utils.MediaUrlValidator.MediaType) 823 */ 824 @Field(Definitions.SOLR_FIELD_MEDIA_TYPE) 825 private void setMediaTypeValue(Integer value){ 826 setMediaType(value == null ? null : MediaType.fromInt(value)); 827 } 828 829 /** 830 * @see #getMediaType() 831 * 832 * @return status value 833 */ 834 public Integer getMediaTypeValue(){ 835 MediaType mediaType = getMediaType(); 836 return (mediaType == null ? null : mediaType.toInt()); 837 } 838 839 /** 840 * @return the timecodes 841 */ 842 public TimecodeList getTimecodes() { 843 return _timecodes; 844 } 845 846 /** 847 * Solr serializing helper method 848 * @param timecodes the timecodes to set in SolrJ format. 849 */ 850 @Field(Definitions.SOLR_FIELD_TIMECODES) 851 public void setSolrTimecodes(List<String> timecodes) { 852 _timecodes = TimecodeList.populateTimecodes(timecodes); 853 } 854 855 /** 856 * Solr serializing helper method 857 * @return the SolrJ formatted list of timecodes 858 */ 859 public List<String> getSolrTimecodes() { 860 return TimecodeList.getSolrTimecodes(_timecodes); 861 } 862 863 /** 864 * @param timecodes the timecodes to set 865 */ 866 public void setTimecodes(TimecodeList timecodes) { 867 _timecodes = timecodes; 868 } 869}