*/
package org.sonar.jpa.entity;
+import javax.persistence.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import javax.persistence.*;
@Entity
@Table(name = SchemaMigration.TABLE_NAME, uniqueConstraints = {@UniqueConstraint(columnNames = {"version"})})
public class SchemaMigration {
public final static int VERSION_UNKNOWN = -1;
- public static final int LAST_VERSION = 139;
+ public static final int LAST_VERSION = 140;
public final static String TABLE_NAME = "schema_migrations";
<class>org.sonar.api.database.configuration.Property</class>
<class>org.sonar.api.qualitymodel.Model</class>
<class>org.sonar.api.qualitymodel.Characteristic</class>
+ <class>org.sonar.api.qualitymodel.CharacteristicProperty</class>
<class>org.sonar.core.plugin.JpaPlugin</class>
<class>org.sonar.core.plugin.JpaPluginFile</class>
private String name;
@Column(name = "depth")
- private int depth=ROOT_DEPTH;
+ private int depth = ROOT_DEPTH;
@Column(name = "characteristic_order")
- private int order=0;
+ private int order = 0;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "quality_model_id")
@ManyToMany(mappedBy = "parents", cascade = CascadeType.ALL)
private List<Characteristic> children = new ArrayList<Characteristic>();
+ @OneToMany(mappedBy = "characteristic", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
+ private List<CharacteristicProperty> properties = new ArrayList<CharacteristicProperty>();
Characteristic() {
}
}
return this;
}
-
+
public Characteristic addChild(Characteristic child) {
- propagateDepth(child, depth+1);
+ propagateDepth(child, depth + 1);
child.addParents(this);
child.setModel(model);
children.add(child);
private static void propagateDepth(Characteristic characteristic, int depth) {
characteristic.setDepth(depth);
for (Characteristic child : characteristic.getChildren()) {
- propagateDepth(child, depth+1);
+ propagateDepth(child, depth + 1);
}
}
Characteristic addParents(Characteristic... pc) {
- if (pc!=null) {
+ if (pc != null) {
Collections.addAll(this.parents, pc);
}
return this;
}
public boolean isRoot() {
- return depth==ROOT_DEPTH;
+ return depth == ROOT_DEPTH;
}
Characteristic setDepth(int i) {
return this;
}
+ public CharacteristicProperty setProperty(String key, String value) {
+ return createProperty(key).setValue(value);
+ }
+
+ public CharacteristicProperty setProperty(String key, double value) {
+ return createProperty(key).setValue(value);
+ }
+
+ public CharacteristicProperty createProperty(String key) {
+ CharacteristicProperty property = new CharacteristicProperty(this, key);
+ properties.add(property);
+ return property;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.qualitymodel;
+
+import javax.persistence.*;
+
+/**
+ * @since 2.3
+ */
+@Entity
+@Table(name = "characteristic_properties")
+public final class CharacteristicProperty {
+
+ @Id
+ @Column(name = "id")
+ @GeneratedValue
+ private Integer id;
+
+ @Column(name = "kee", nullable = true, length = 100)
+ private String key;
+
+ @Column(name = "value", nullable = true)
+ private Double value;
+
+ @Column(name = "text_value", nullable = true, length = 4000)
+ private String textValue;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "characteristic_id", updatable = true, nullable = false)
+ private Characteristic characteristic;
+
+ CharacteristicProperty(Characteristic characteristic, String key) {
+ this.characteristic = characteristic;
+ this.key = key;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ CharacteristicProperty setId(Integer i) {
+ this.id = i;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public CharacteristicProperty setKey(String s) {
+ this.key = s;
+ return this;
+ }
+
+ public String getValue() {
+ return textValue;
+ }
+
+ public Double getValueAsDouble() {
+ return value;
+ }
+
+ public Long getValueAsLong() {
+ if (value!=null) {
+ return value.longValue();
+ }
+ return null;
+ }
+
+ public Boolean getValueAsBoolean() {
+ if (textValue!=null) {
+ return Boolean.parseBoolean(textValue);
+ }
+ return null;
+ }
+
+ public CharacteristicProperty setValue(String s) {
+ this.textValue = s;
+ return this;
+ }
+
+ public CharacteristicProperty setValue(Boolean b) {
+ this.textValue = (b==null ? null : String.valueOf(b));
+ return this;
+ }
+
+ public CharacteristicProperty setValue(Long l) {
+ this.textValue = (l==null ? null : String.valueOf(l));
+ return this;
+ }
+
+
+ public CharacteristicProperty setValue(Double d) {
+ this.value = d;
+ return this;
+ }
+
+ Characteristic getCharacteristic() {
+ return characteristic;
+ }
+
+ CharacteristicProperty setCharacteristic(Characteristic c) {
+ this.characteristic = c;
+ return this;
+ }
+}
belongs_to :rule
belongs_to :quality_model
-
- validates_uniqueness_of :name, :scope => :quality_model_id, :case_sensitive => false, :if => Proc.new { |c| c.rule_id.nil? }
- validates_length_of :name, :in => 1..100, :allow_blank => false, :if => Proc.new { |c| c.rule_id.nil? }
+ has_many :characteristic_properties, :dependent => :delete_all
+
+ validates_uniqueness_of :name, :scope => [:quality_model_id, :enabled], :case_sensitive => false, :if => Proc.new { |c| c.rule_id.nil? && c.enabled }
+ validates_length_of :name, :in => 1..NAME_MAX_SIZE, :allow_blank => false, :if => Proc.new { |c| c.rule_id.nil? }
validates_presence_of :quality_model
def root?
def parent
parents.empty? ? nil : parents[0]
end
+
+ def enabled_children
+ children.select{|c| c.enabled}
+ end
+
+ def properties
+ characteristic_properties
+ end
+
+ def property(key)
+ properties.each do |p|
+ return p if p.key==key
+ end
+ nil
+ end
+
+ # the property is not saved
+ def set_property(key, value)
+ p=property(key)
+ unless p
+ p=characteristic_properties.build(:kee => key)
+ end
+ if (value.is_a?(Fixnum) || value.is_a?(Float))
+ p.value=value.to_f
+ else
+ p.text_value=value.to_s
+ end
+ p
+ end
+
+ def save_property(key, value)
+ p=set_property(key, value)
+ p.save
+ end
+
+ def property_value(key, default_value=nil)
+ p=property(key)
+ if p
+ (p.value ? p.value.to_f : nil) || p.text_value || default_value
+ else
+ default_value
+ end
+ end
end
\ No newline at end of file
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2009 SonarSource SA
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class CharacteristicProperty < ActiveRecord::Base
+ KEY_MAX_SIZE=100
+
+ belongs_to :characteristic
+ validates_length_of :kee, :in => 1..KEY_MAX_SIZE, :allow_blank => false
+
+ def key
+ kee
+ end
+
+end
\ No newline at end of file
has_many :characteristics, :dependent => :delete_all
- def root_characteristics
+ def root_characteristics(only_enabled=true)
@roots ||=
begin
characteristics.select do |c|
- c.parents.empty?
+ c.parents.empty? && (!only_enabled || c.enabled)
end
end
end
- def characteristics_with_rule
+ def characteristics_with_rule(only_enabled=true)
@characteristics_with_rule ||=
begin
characteristics.select do |c|
- !c.rule_id.nil?
+ (!c.rule_id.nil?) && (!only_enabled || c.enabled)
end
end
end
- def characteristics_without_rule
+ def characteristics_without_rule(only_enabled=true)
@characteristics_without_rule ||=
begin
characteristics.select do |c|
- c.rule_id.nil?
+ c.rule_id.nil? && (!only_enabled || c.enabled)
end
end
end
+ # be careful, can return disabled characteristic
def characteristic(id)
@characteristics_by_id ||=
begin
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2009 SonarSource SA
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class CreateCharacteristicProperties < ActiveRecord::Migration
+
+ def self.up
+ create_table 'characteristic_properties' do |t|
+ t.column 'characteristic_id', :integer
+ t.column 'kee', :string, :limit => 100, :null => true
+ t.column :value, :decimal, :null => true, :precision => 30, :scale => 20
+ t.column :text_value, :string, :limit => 4000, :null => true
+ end
+ end
+
+end