001package org.cpsolver.instructor.model; 002 003/** 004 * Attributes of an instructor. Each instructor can have a number of attributes and there are attribute preferences on teaching requests. 005 * Each attribute has an id, a name and a {@link Type}. 006 * 007 * @version IFS 1.3 (Instructor Sectioning)<br> 008 * Copyright (C) 2016 Tomas Muller<br> 009 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 010 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 011 * <br> 012 * This library is free software; you can redistribute it and/or modify 013 * it under the terms of the GNU Lesser General Public License as 014 * published by the Free Software Foundation; either version 3 of the 015 * License, or (at your option) any later version. <br> 016 * <br> 017 * This library is distributed in the hope that it will be useful, but 018 * WITHOUT ANY WARRANTY; without even the implied warranty of 019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 020 * Lesser General Public License for more details. <br> 021 * <br> 022 * You should have received a copy of the GNU Lesser General Public 023 * License along with this library; if not see 024 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 025 */ 026public class Attribute { 027 private Long iAttributeId; 028 private String iAttributeName; 029 private Type iType; 030 031 /** 032 * Constructor 033 * @param attributeId attribute id 034 * @param attributeName attribute name 035 * @param type attribute type 036 */ 037 public Attribute(long attributeId, String attributeName, Type type) { 038 iAttributeId = attributeId; 039 iAttributeName = attributeName; 040 iType = type; 041 } 042 043 /** 044 * Attribute id that was provided in the constructor 045 * @return attribute id 046 */ 047 public Long getAttributeId() { return iAttributeId; } 048 049 /** 050 * Attribute name that was provided in the constructor 051 * @return attribute name 052 */ 053 public String getAttributeName() { return iAttributeName == null ? "A" + iAttributeId : iAttributeName; } 054 055 /** 056 * Attribute type that was provided in the constructor 057 * @return attribute type 058 */ 059 public Type getType() { return iType; } 060 061 @Override 062 public int hashCode() { 063 return (getAttributeId() == null ? getAttributeName().hashCode() : getAttributeId().hashCode()); 064 } 065 066 @Override 067 public boolean equals(Object o) { 068 if (o == null || !(o instanceof Attribute)) return false; 069 Attribute a = (Attribute)o; 070 return getAttributeId() == null ? getAttributeName().equals(a.getAttributeName()) : getAttributeId().equals(a.getAttributeId()); 071 } 072 073 @Override 074 public String toString() { return getAttributeName() + " (" + getType() + ")"; } 075 076 /** 077 * Attribute type. Each type has an id and a name. It can also define whether attributes of this type are required and/or conjunctive. 078 * If an attribute is required, this means that only instructors that have the attribute can be used, even if it is only preferred. This 079 * allows to put different preferences on multiple attribute that are required. 080 * If a teaching requests require two attributes that are of the same type which is conjunctive, only instructors that have BOTH attributes can be used. 081 * It the type is disjunctive (not conjunctive), it is sufficient for the instructor to have one of the two required attributes. 082 */ 083 public static class Type { 084 private Long iTypeId; 085 private String iTypeName; 086 private boolean iRequired; 087 private boolean iConjunctive; 088 089 /** 090 * Constructor 091 * @param typeId attribute type id 092 * @param typeName attribute type name 093 * @param conjunctive is attribute type conjunctive (if two attributes are required a student must have both). 094 * @param required 095 */ 096 public Type(long typeId, String typeName, boolean conjunctive, boolean required) { 097 iTypeId = typeId; 098 iTypeName = typeName; 099 iConjunctive = conjunctive; 100 iRequired = required; 101 } 102 103 /** 104 * Attribute type id that was provided in the constructor 105 * @return attribute type id 106 */ 107 public Long getTypeId() { return iTypeId; } 108 109 /** 110 * Attribute type name that was provided in the constructor 111 * @return attribute type name 112 */ 113 public String getTypeName() { return iTypeName == null ? "T" + iTypeId : iTypeName; } 114 115 /** 116 * If an attribute is required, this means that only instructors that have the attribute can be used, even if it is only preferred. This 117 * allows to put different preferences on multiple attribute that are required. 118 * @return true if this attribute type is required 119 */ 120 public boolean isRequired() { return iRequired; } 121 122 /** 123 * If a teaching requests require two attributes that are of the same type which is conjunctive, only instructors that have BOTH attributes can be used. 124 * It the type is disjunctive (not conjunctive), it is sufficient for the instructor to have one of the two required attributes. 125 * @return true if this attribute type is conjunctive, false if disjunctive 126 */ 127 public boolean isConjunctive() { return iConjunctive; } 128 129 @Override 130 public int hashCode() { 131 return getTypeId() == null ? getTypeName().hashCode() : getTypeId().hashCode(); 132 } 133 134 @Override 135 public boolean equals(Object o) { 136 if (o == null || !(o instanceof Type)) return false; 137 Type t = (Type)o; 138 return getTypeId() == null ? getTypeName().equals(t.getTypeName()) : getTypeId().equals(t.getTypeId()); 139 } 140 141 @Override 142 public String toString() { return getTypeName(); } 143 } 144 145}