bug 9651: Adding network tags

Also changes in Request logging.
This commit is contained in:
Alex Huang 2011-05-23 15:51:42 -07:00
parent e22d99f70d
commit 0dfc44582b
18 changed files with 810 additions and 487 deletions

View File

@ -18,6 +18,7 @@
package com.cloud.agent.api.to;
import java.net.URI;
import java.util.List;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
@ -38,6 +39,7 @@ public class NetworkTO {
protected URI broadcastUri;
protected URI isolationUri;
protected boolean isSecurityGroupEnabled;
protected String[] tags;
public NetworkTO() {
}
@ -86,6 +88,14 @@ public class NetworkTO {
this.type = type;
}
public void setTags(List<String> tags) {
this.tags = tags.toArray(new String[tags.size()]);
}
public String[] getTags() {
return tags;
}
public void setSecurityGroupEnabled(boolean enabled) {
this.isSecurityGroupEnabled = enabled;
}

View File

@ -228,4 +228,6 @@ public interface Network extends ControlledEntity {
boolean isSecurityGroupEnabled();
List<String> getTags();
}

View File

@ -19,13 +19,14 @@
package com.cloud.network;
import java.net.URI;
import java.util.List;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
public class NetworkProfile implements Network{
public class NetworkProfile implements Network {
private long id;
private long dataCenterId;
private long ownerId;
@ -49,6 +50,7 @@ public class NetworkProfile implements Network{
private boolean isDefault;
private String networkDomain;
private boolean isSecurityGroupEnabled;
private List<String> tags;
public NetworkProfile(Network network) {
this.id = network.getId();
@ -74,6 +76,11 @@ public class NetworkProfile implements Network{
this.isSecurityGroupEnabled = network.isSecurityGroupEnabled();
}
@Override
public List<String> getTags() {
return tags;
}
public String getDns1() {
return dns1;
}

View File

@ -22,6 +22,7 @@
package com.cloud.vm;
import java.net.URI;
import java.util.List;
import com.cloud.network.Network;
import com.cloud.network.Networks.AddressFormat;
@ -53,11 +54,16 @@ public class NicProfile {
String dns2;
Integer networkRate;
boolean isSecurityGroupEnabled;
List<String> tags;
public String getDns1() {
return dns1;
}
public List<String> getTags() {
return tags;
}
public String getDns2() {
return dns2;
}
@ -226,6 +232,7 @@ public class NicProfile {
this.netmask = nic.getNetmask();
this.isSecurityGroupEnabled = network.isSecurityGroupEnabled();
this.vmId = nic.getInstanceId();
this.tags = network.getTags();
if (networkRate != null) {
this.networkRate = networkRate;

View File

@ -23,8 +23,10 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
import com.cloud.exception.UnsupportedVersionException;
@ -64,6 +66,7 @@ public class Request {
protected static final Gson s_gson = GsonHelper.getGson();
protected static final Gson s_gogger = GsonHelper.getGsonLogger();
protected static final Logger s_gsonLogger = GsonHelper.getLogger();
public enum Version {
v1, // using gson to marshall
@ -278,47 +281,69 @@ public class Request {
public void logD(String msg, boolean logContent) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(log(msg, logContent));
String log = log(msg, logContent, Level.DEBUG);
if (log != null) {
s_logger.debug(log);
}
}
}
public void logT(String msg, boolean logD) {
if (s_logger.isTraceEnabled()) {
s_logger.trace(log(msg, true));
String log = log(msg, true, Level.TRACE);
if (log != null) {
s_logger.trace(log);
}
} else if (logD && s_logger.isDebugEnabled()) {
s_logger.debug(log(msg, false));
String log = log(msg, false, Level.DEBUG);
if (log != null) {
s_logger.debug(log);
}
}
}
protected String log(String msg, boolean logContent) {
StringBuilder buf = new StringBuilder("Seq ");
buf.append(_agentId).append("-").append(_seq).append(": ");
buf.append(msg);
buf.append("{ ").append(getType());
buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
protected String log(String msg, boolean logContent, Level level) {
StringBuilder content = new StringBuilder();
if (logContent) {
buf.append(", Ver: ").append(_ver.toString());
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
if (_cmds != null) {
if (_cmds == null) {
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
}
try {
s_gogger.toJson(_cmds, buf);
s_gogger.toJson(_cmds, content);
} catch (Throwable e) {
StringBuilder buff = new StringBuilder();
for (Command cmd : _cmds) {
buff.append(cmd.getClass().getName()).append("/");
buff.append(cmd.getClass().getSimpleName()).append("/");
}
s_logger.error("Gson serialization error " + buff.toString(), e);
assert false : "More gson errors on " + buff.toString();
return "";
}
} else if (_content != null) {
buf.append(_content.subSequence(0, 32));
if (content.length() <= 4) {
return null;
}
} else {
buf.append("I've got nada here!");
assert false : "How can both commands and content be null? What are we sending here?";
if (_cmds == null) {
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
}
content.append("{ ");
for (Command cmd : _cmds) {
content.append(cmd.getClass().getSimpleName()).append(", ");
}
content.replace(content.length() - 2, content.length(), " }");
}
StringBuilder buf = new StringBuilder("Seq ");
buf.append(_agentId).append("-").append(_seq).append(": ");
buf.append(msg);
buf.append(" { ").append(getType());
buf.append(", MgmtId: ").append(_mgmtId).append(", via: ").append(_via);
buf.append(", Ver: ").append(_ver.toString());
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
buf.append(content);
buf.append(" }");
return buf.toString();
}

View File

@ -75,4 +75,8 @@ public class GsonHelper {
public final static Gson getGsonLogger() {
return s_gogger;
}
public final static Logger getLogger() {
return s_logger;
}
}

View File

@ -54,7 +54,7 @@ public class RequestTest extends TestCase {
Level level = logger.getLevel();
logger.setLevel(Level.DEBUG);
String log = sreq.log("Debug", true);
String log = sreq.log("Debug", true, Level.DEBUG);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (!log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -62,7 +62,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password"));
logger.setLevel(Level.TRACE);
log = sreq.log("Trace", true);
log = sreq.log("Trace", true, Level.TRACE);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -70,7 +70,7 @@ public class RequestTest extends TestCase {
assert (!log.contains("password"));
logger.setLevel(Level.INFO);
sreq.log("Info", true);
sreq.log("Info", true, Level.INFO);
assert (log.contains(UpdateHostPasswordCommand.class.getSimpleName()));
assert (log.contains(SecStorageFirewallCfgCommand.class.getSimpleName()));
assert (!log.contains(GetHostStatsCommand.class.getSimpleName()));
@ -127,6 +127,28 @@ public class RequestTest extends TestCase {
}
public void testLogging() {
GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101);
Request sreq = new Request(2, 3, new Command[] { cmd3 }, true, true);
sreq.setSequence(1);
Logger logger = Logger.getLogger(GsonHelper.class);
Level level = logger.getLevel();
logger.setLevel(Level.DEBUG);
String log = sreq.log("Debug", true, Level.DEBUG);
assert (log == null);
log = sreq.log("Debug", false, Level.DEBUG);
assert (log != null);
logger.setLevel(Level.TRACE);
log = sreq.log("Trace", true, Level.TRACE);
assert (log.contains(GetHostStatsCommand.class.getSimpleName()));
s_logger.debug(log);
logger.setLevel(level);
}
protected void compareRequest(Request req1, Request req2) {
assert req1.getSequence() == req2.getSequence();
assert req1.getAgentId() == req2.getAgentId();

View File

@ -50,6 +50,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIsolationuri(profile.getIsolationUri());
to.setNetworkRateMbps(profile.getNetworkRate());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
to.setTags(profile.getTags());
return to;
}
@ -82,6 +83,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
return to;
}
@Override
public long getCommandHostDelegation(long hostId, Command cmd) {
return hostId;
}

View File

@ -18,7 +18,9 @@
package com.cloud.network;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -32,6 +34,7 @@ import javax.persistence.Transient;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils;
@ -137,6 +140,9 @@ public class NetworkVO implements Network {
@Column(name="is_security_group_enabled")
boolean securityGroupEnabled;
@Transient
List<String> tags;
public NetworkVO() {
}
@ -233,6 +239,22 @@ public class NetworkVO implements Network {
return id;
}
@Override
public List<String> getTags() {
return tags != null ? tags : new ArrayList<String>();
}
public void addTag(String tag) {
if (tags == null) {
tags = new ArrayList<String>();
}
tags.add(tag);
}
public void setTags(List<String> tags) {
this.tags = tags;
}
@Override
public GuestIpType getGuestType() {
return guestType;
@ -436,14 +458,16 @@ public class NetworkVO implements Network {
return NetUtils.isNetworkAWithinNetworkB(this.cidr, that.cidr);
}
public boolean isImplemented() {
return broadcastUri != null && cidr != null && gateway != null && mode != null && broadcastDomainType != null;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder("Ntwk[");
buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]");
return buf.toString();
}
private static NetworkDao _networkDao = null;
static void init(NetworkDao networkDao) {
_networkDao = networkDao;
}
}

View File

@ -55,6 +55,8 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class);
NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class);
NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
NetworkTagDaoImpl _tagDao = ComponentLocator.inject(NetworkTagDaoImpl.class);
final TableGenerator _tgMacAddress;
Random _rand = new Random(System.currentTimeMillis());
long _prefix = 0x2;
@ -143,6 +145,11 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
return listBy(sc);
}
// @Override
// public void loadTags(NetworkVO network) {
// network.setTags(_tagDao.getTags(network.getId()));
// }
@Override
public List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId) {
@ -166,24 +173,28 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
}
@Override @DB
public NetworkVO persist(NetworkVO config, boolean gc) {
public NetworkVO persist(NetworkVO network, boolean gc) {
Transaction txn = Transaction.currentTxn();
txn.start();
config = super.persist(config);
addAccountToNetworkConfiguration(config.getId(), config.getAccountId(), true);
NetworkOpVO op = new NetworkOpVO(config.getId(), gc);
NetworkVO newNetwork = super.persist(network);
addAccountToNetwork(network.getId(), network.getAccountId(), true);
NetworkOpVO op = new NetworkOpVO(network.getId(), gc);
_opDao.persist(op);
for (String tag : network.getTags()) {
_tagDao.persist(new NetworkTagVO(network.getId(), tag));
}
txn.commit();
return config;
newNetwork.setTags(network.getTags());
return newNetwork;
}
@Override
public void addAccountToNetwork(long configurationId, long accountId) {
addAccountToNetworkConfiguration(configurationId, accountId, false);
public void addAccountToNetwork(long networkId, long accountId) {
addAccountToNetwork(networkId, accountId, false);
}
protected void addAccountToNetworkConfiguration(long configurationId, long accountId, boolean isOwner) {
NetworkAccountVO account = new NetworkAccountVO(configurationId, accountId, isOwner);
protected void addAccountToNetwork(long networkId, long accountId, boolean isOwner) {
NetworkAccountVO account = new NetworkAccountVO(networkId, accountId, isOwner);
_accountsDao.persist(account);
}
@ -243,8 +254,9 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
@Override
public List<NetworkVO> listByZoneSecurityGroup(Long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
if (zoneId != null)
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
sc.setParameters("securityGroup", true);
return search(sc, null);
}
@ -277,12 +289,12 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
}
@Override
public void addDomainToNetwork(long configurationId, long domainId) {
addDomainToNetworkConfiguration(configurationId, domainId);
public void addDomainToNetwork(long networkId, long domainId) {
addDomainToNetworknetwork(networkId, domainId);
}
protected void addDomainToNetworkConfiguration(long configurationId, long domainId) {
NetworkDomainVO domain = new NetworkDomainVO(configurationId, domainId);
protected void addDomainToNetworknetwork(long networkId, long domainId) {
NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId);
_domainsDao.persist(domain);
}

View File

@ -0,0 +1,62 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.dao;
import java.util.List;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
public class NetworkTagDaoImpl extends GenericDaoBase<NetworkTagVO, Long> implements GenericDao<NetworkTagVO, Long> {
private final GenericSearchBuilder<NetworkTagVO, String> TagSearch;
private final SearchBuilder<NetworkTagVO> AllFieldsSearch;
protected NetworkTagDaoImpl() {
super();
TagSearch = createSearchBuilder(String.class);
TagSearch.selectField(TagSearch.entity().getTag());
TagSearch.and("networkid", TagSearch.entity().getNetworkId(), Op.EQ);
TagSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.and("networkid", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.and("tag", AllFieldsSearch.entity().getTag(), Op.EQ);
AllFieldsSearch.done();
}
public List<String> getTags(long networkId) {
SearchCriteria<String> sc = TagSearch.create();
sc.setParameters("networkid", networkId);
return customSearch(sc, null);
}
public int clearTags(long networkId) {
SearchCriteria<NetworkTagVO> sc = AllFieldsSearch.create();
sc.setParameters("networkid", networkId);
return remove(sc);
}
}

View File

@ -0,0 +1,68 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* This class is just used to work with the DAO. It shouldn't be used anywhere.
*
*/
@Entity
@Table(name = "network_tags")
public class NetworkTagVO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "network_id")
private long networkId;
@Column(name = "tag")
private String tag;
/**
* There should never be a public constructor for this class. Since it's
* only here to define the table for the DAO class.
*/
protected NetworkTagVO() {
}
protected NetworkTagVO(long networkId, String tag) {
this.networkId = networkId;
this.tag = tag;
}
public long getId() {
return id;
}
public long getNetworkId() {
return networkId;
}
public String getTag() {
return tag;
}
}

View File

@ -112,6 +112,7 @@ DROP TABLE IF EXISTS `cloud`.`storage_pool_work`;
DROP TABLE IF EXISTS `cloud`.`user_vm_details`;
DROP TABLE IF EXISTS `cloud`.`vpn_users`;
DROP TABLE IF EXISTS `cloud`.`data_center_details`;
DROP TABLE IF EXISTS `cloud`.`network_tags`;
CREATE TABLE `cloud`.`version` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
@ -190,6 +191,15 @@ CREATE TABLE `cloud`.`networks` (
INDEX `i_networks__removed`(`removed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`network_tags` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`network_id` bigint unsigned NOT NULL COMMENT 'id of the network',
`tag` varchar(255) NOT NULL COMMENT 'tag',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
UNIQUE KEY(`network_id`, `tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`account_network_ref` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`account_id` bigint unsigned NOT NULL COMMENT 'account id',

View File

@ -31,6 +31,14 @@ CREATE TABLE `cloud`.`cmd_exec_log` (
CONSTRAINT `fk_cmd_exec_log_ref__inst_id` FOREIGN KEY (`instance_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`network_tags` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`network_id` bigint unsigned NOT NULL COMMENT 'id of the network',
`tag` varchar(255) NOT NULL COMMENT 'tag',
PRIMARY KEY (`id`),
CONSTRAINT `fk_network_tags__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
UNIQUE KEY(`network_id`, `tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud`.`firewall_rules_cidrs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',

View File

@ -49,6 +49,7 @@ import javax.persistence.EmbeddedId;
import javax.persistence.EntityExistsException;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.OneToMany;
import javax.persistence.TableGenerator;
import net.sf.cglib.proxy.Callback;
@ -134,6 +135,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
protected Map<String, Attribute[]> _idAttributes;
protected Map<String, TableGenerator> _tgs;
protected final Map<String, Attribute> _allAttributes;
protected List<Attribute> _oneToManyAttributes;
protected final Map<Pair<String, String>, Attribute> _allColumns;
protected Enhancer _enhancer;
protected Factory _factory;
@ -222,6 +224,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
_deleteSqls = generator.buildDeleteSqls();
_removed = generator.getRemovedAttribute();
_tgs = generator.getTableGenerators();
_oneToManyAttributes = generator.getOneToManyAttributes();
TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
if (tg != null) {
@ -1376,6 +1379,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
setField(entity, result, meta, index);
}
for (Attribute attr : _oneToManyAttributes) {
OneToMany otm = attr.field.getAnnotation(OneToMany.class);
}
}
@Override

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
@ -36,6 +37,8 @@ import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.TableGenerator;
@ -51,11 +54,13 @@ public class SqlGenerator {
ArrayList<Class<?>> _tables;
LinkedHashMap<String, List<Attribute>> _ids;
HashMap<String, TableGenerator> _generators;
ArrayList<Attribute> _otmAttrs;
public SqlGenerator(Class<?> clazz) {
_clazz = clazz;
_tables = new ArrayList<Class<?>>();
_attributes = new ArrayList<Attribute>();
_otmAttrs = new ArrayList<Attribute>();
_embeddeds = new ArrayList<Field>();
_ids = new LinkedHashMap<String, List<Attribute>>();
_generators = new HashMap<String, TableGenerator>();
@ -135,9 +140,31 @@ public class SqlGenerator {
attrs.add(attr);
}
if (field.getAnnotation(OneToMany.class) != null) {
assert supportsOneToMany(field) : "Doesn't support One To Many";
_otmAttrs.add(attr);
} else {
_attributes.add(attr);
}
}
}
protected boolean supportsOneToMany(Field field) {
OneToMany otm = field.getAnnotation(OneToMany.class);
if (otm.fetch() == FetchType.LAZY) {
assert (false) : "Doesn't support laz fetch: " + field.getName();
return false;
}
for (CascadeType cascade : otm.cascade()) {
if (cascade == CascadeType.ALL || cascade == CascadeType.PERSIST || cascade == CascadeType.MERGE || cascade == CascadeType.REMOVE) {
assert (false) : "Doesn't support " + cascade + " for " + field.getName();
return false;
}
}
return true;
}
public Map<String, TableGenerator> getTableGenerators() {
return _generators;
@ -237,6 +264,10 @@ public class SqlGenerator {
}
}
public List<Attribute> getOneToManyAttributes() {
return _otmAttrs;
}
public Attribute findAttribute(String name) {
for (Attribute attr : _attributes) {
if (attr.columnName == name || attr.columnName.equals(name)) {

View File

@ -0,0 +1,22 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package javax.persistence;
public interface ElementCollection {
}