@@ -19,18 +19,18 @@ | |||
*/ | |||
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"; | |||
@@ -10,6 +10,7 @@ | |||
<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> | |||
@@ -52,10 +52,10 @@ public final class Characteristic implements Comparable<Characteristic> { | |||
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") | |||
@@ -84,6 +84,8 @@ public final class Characteristic implements Comparable<Characteristic> { | |||
@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() { | |||
} | |||
@@ -154,9 +156,9 @@ public final class Characteristic implements Comparable<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); | |||
@@ -166,12 +168,12 @@ public final class Characteristic implements Comparable<Characteristic> { | |||
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; | |||
@@ -211,7 +213,7 @@ public final class Characteristic implements Comparable<Characteristic> { | |||
} | |||
public boolean isRoot() { | |||
return depth==ROOT_DEPTH; | |||
return depth == ROOT_DEPTH; | |||
} | |||
Characteristic setDepth(int i) { | |||
@@ -237,6 +239,20 @@ public final class Characteristic implements Comparable<Characteristic> { | |||
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) { |
@@ -0,0 +1,123 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -28,9 +28,10 @@ class Characteristic < ActiveRecord::Base | |||
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? | |||
@@ -53,4 +54,47 @@ class Characteristic < ActiveRecord::Base | |||
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 |
@@ -0,0 +1,30 @@ | |||
# | |||
# 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 |
@@ -24,33 +24,34 @@ class QualityModel < ActiveRecord::Base | |||
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 |
@@ -0,0 +1,31 @@ | |||
# | |||
# 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 |