I have two DataSource beans and two DataSourceInitializer beans, one for each DataSource. These configurations are in different class files, but both DataSourceInitializers attempt to set up DataSourceOne.
How can I tell the DataSourceInitializerTwo to use (inject?) the DataSourceTwo bean?
//Data Source 1
#Bean
public DataSource dataSourceOne() {
JdbcDataSource ds = new JdbcDataSource();
ds.setUrl("jdbc:h2:mem:app1db;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2;INIT=CREATE SCHEMA IF NOT EXISTS app1\\;SET SCHEMA app1");
ds.setUser("app1");
ds.setPassword("app1");
return ds;
}
#Bean
public DataSourceInitializer dataSourceInitializerOne(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(DatabasePopulator());
return initializer;
}
//Data Source 2
#Bean
public DataSource dataSourceTwo() {
JdbcDataSource ds = new JdbcDataSource();
ds.setUrl("jdbc:h2:mem:app1db;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2;INIT=CREATE SCHEMA IF NOT EXISTS app2\\;SET SCHEMA app2");
ds.setUser("app2");
ds.setPassword("app2");
return ds;
}
#Bean
public DataSourceInitializer dataSourceInitializerTwo(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSourceTwo);
initializer.setDatabasePopulator(databasePopulatorTwo());
return initializer;
}
The DataSourceInitializer method appears to inject a DataSource bean based on parameter name. Simply make the name of your method that returns a DataSource match the name of the DataSource parameter that your appropriate initializer method takes in.
//Data Source 1
#Bean
public DataSource dataSourceOne() {
JdbcDataSource ds = new JdbcDataSource();
ds.setUrl("jdbc:h2:mem:app1db;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2;INIT=CREATE SCHEMA IF NOT EXISTS app1\\;SET SCHEMA app1");
ds.setUser("app1");
ds.setPassword("app1");
return ds;
}
#Bean
public DataSourceInitializer dataSourceInitializerOne(final DataSource dataSourceOne) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSourceOne);
initializer.setDatabasePopulator(DatabasePopulator());
return initializer;
}
//Data Source 2
#Bean
public DataSource dataSourceTwo() {
JdbcDataSource ds = new JdbcDataSource();
ds.setUrl("jdbc:h2:mem:app1db;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2;INIT=CREATE SCHEMA IF NOT EXISTS app2\\;SET SCHEMA app2");
ds.setUser("app2");
ds.setPassword("app2");
return ds;
}
#Bean
public DataSourceInitializer dataSourceInitializerTwo(final DataSource dataSourceTwo) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSourceTwo);
initializer.setDatabasePopulator(databasePopulatorTwo());
return initializer;
}
Related
I have an object Bean containing a List<String>. I would like to "bind" this list to an ObservableList so when an item is added to or removed from the original list, the ObservableList is updated (which then triggers the listeners that monitor the ObservableList).
I found this question whose answer shows how to wrap a simple String into a JavaFX StringProperty using JavaBeanStringPropertyBuilder.
I tried to do the same thing but replacing the String with a List<String> as shown below:
public class Bean {
private final List<String> nameList;
private final PropertyChangeSupport propertySupport ;
public Bean() {
this.nameList = new ArrayList<>();
this.propertySupport = new PropertyChangeSupport(this);
}
public List<String> getNameList() {
return nameList;
}
public void setNameList(List<String> nameList)
{
List<String> oldList = new ArrayList<>(this.nameList);
this.nameList.clear();
this.nameList.addAll(nameList);
propertySupport.firePropertyChange("nameList", oldList, this.nameList);
}
public void addName(String name) {
List<String> oldList = new ArrayList<>(this.nameList);
this.nameList.add(name);
propertySupport.firePropertyChange("nameList", oldList, this.nameList);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
}
Bean bean = new Bean();
JavaBeanObjectProperty<List<String>> listProperty = null;
try
{
listProperty = JavaBeanObjectPropertyBuilder.create().bean(bean).name("nameList").build();
} catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
listProperty.addListener((ObservableValue<? extends List<String>> obs, List<String> oldName, List<String> newName) ->
{
System.out.println("List changed");
});
bean.setNameList(Arrays.asList("George", "James"));
But the listener is not triggered after calling setNameList() and I don't know what I'm missing.
Could you help me please?
A change listener registered with a Property<T> will only be notified if the value of the property actually changes. That is, the set(T newValue) method is implemented something like this:
public void set(T newValue) {
T oldValue = this.get();
if (! oldValue.equals(newValue)) {
// notify change listeners...
}
}
The JavaBeanObjectPropertyBuilder is going to create a JavaBeanObjectProperty<List<String>> (an implementation of Property<List<String>>) and set its value to the result of calling bean.getNameList(). I.e. the value held internally by listProperty is a reference to bean.nameList.
The JavaBeanObjectProperty also registers a listener via the call to bean.addPropertyChangeListener(...). When
propertySupport.firePropertyChange("nameList", oldList, this.nameList);
is invoked, the internal listener in JavaBeanObjectProperty will set its own value to the new value fired by the property change support; i.e. it will call
set(bean.nameList);
However, since this is just a reference to the current value of the property, no change listener registered with listProperty will be notified (basically, no change has occurred).
To clarify, if it helps: the content of the List<String> returned by listProperty.get() will change when you call
this.nameList.clear();
and
this.nameList.addAll(nameList);
in the bean (because the listProperty references bean.nameList), but the actual list reference itself has not changed.
You can test this with, e.g.
Bean bean = new Bean();
JavaBeanObjectProperty<List<String>> listProperty = null;
try
{
listProperty = JavaBeanObjectPropertyBuilder.create().bean(bean).name("nameList").build();
} catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
listProperty.addListener((ObservableValue<? extends List<String>> obs, List<String> oldName, List<String> newName) ->
{
System.out.println("List changed");
});
List<String> oldList = listProperty.get();
bean.setNameList(Arrays.asList("George", "James"));
List<String> newList = listProperty.get();
System.out.println(oldList);
System.out.println(newList);
System.out.println(oldList == newList);
The best fix is simply to use an ObservableList in your Bean class:
public class Bean {
private final ObservableList<String> nameList;
public Bean() {
this.nameList = FXCollections.observableArrayList<>();
}
public ObservableList<String> getNameList() {
return nameList;
}
public void addName(String name) {
this.nameList.add(name);
}
}
Note you don't lose the functionality provided by setNameList(...); you can do
bean.getNameList().setAll(...);
if you want to set the entire content of the list. If you want the same API, you can use a ListProperty instead of the ObservableList.
The test code you have then becomes
Bean bean = new Bean();
bean.getNameList().addListener((ListChangeListener.Change<? extends String> change) ->
{
System.out.println("List changed");
});
bean.getNameList().setAll("George", "James");
As stated in the comments in the question, I don't really understand having any restriction preventing the use of ObservableList in the model; indeed this is exactly the use case for which ObservableList (along with the properties and bindings API) was designed.
There is no adapter designed for use with observable lists in the same way as there are Java Bean adapters for simple properties. Thus if you really wanted to avoid use of ObservableList in your model class (which, again, doesn't really make sense to me), you would have to implement your own listener notification for the Bean:
public class Bean {
private final List<String> nameList ;
private final List<Consumer<String>> nameAddedListeners ;
private final List<Consumer<List<String>>> nameListReplacedListeners ;
public Bean() {
this.nameList = new ArrayList<>();
this.nameAddedListeners = new ArrayList<>();
this.nameListReplacedListeners = new ArrayList<>();
}
public List<String> getNameList() {
return nameList ;
}
public void setNameList(List<String> newNames) {
this.nameList.setAll(newNames);
nameListReplacedListeners.forEach(listener -> listener.accept(newNames));
}
public void addName(String name) {
this.nameList.add(name);
nameAddedListeners.forEach(listener -> listener.accept(name));
}
public void addNameListReplacedListener(Consumer<List<String>> listener) {
nameListReplacedListeners.add(listener);
}
public void addNameAddedListener(Consumer<String> listener) {
nameAddedListeners.add(listener);
}
}
Now you could do
Bean bean = new Bean();
bean.addNameListReplacedListener(list -> System.out.println("Names changed"));
bean.setNameList(List.of("George", "James"));
or you could effectively create an adapter:
Bean bean = new Bean();
ObservableList<String> names = FXCollections.observableArrayList(bean.getNameList());
bean.addNameAddedListener(names::add);
bean.addNameListReplacedListener(names::setAll);
etc.
I implemented custom IIdentityMessageService class. My implementation simply put messages into database. I use Dependency resolver to create instance of repository class.
public class QueueSmsService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
var smsRepository = DependencyResolver.Current.GetService<ISmsRepository>();
Sms smsMessage = new Sms()
{
Priority = (int)MessagePriority.High,
NumberTo = message.Destination,
Body = message.Body
};
return smsRepository.InsertAndSubmitAsync(smsMessage);
}
}
Unfortunately there is a problem with HttpContext being null. Maybe if I inject repository in contructor would solve the problem? Can I somehow inject repository in contructor? Maybe there is another solution to eliminate the HttpContect == null problem? Right now QueueSmsService is created like below in:
var manager = new AppUserManager(new AppUserStore(context.Get<DataContext>()));
manager.RegisterTwoFactorProvider("SMS", new PhoneNumberTokenProvider<User, int>
{
MessageFormat = "Kod autentykujÄ…cy: {0}"
});
manager.EmailService = new QueueEmailService();
manager.SmsService = new QueueSmsService();
HttpContext is used in repository class
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
private IDataContext dataContext;
private readonly IHttpContextFactory httpContextFactory;
protected static Logger logger = LogManager.GetCurrentClassLogger();
public RepositoryBase(IDataContext dataContext, IHttpContextFactory httpContext)
{
if (httpContext == null) throw new ArgumentNullException("httpContextFactory");
this.httpContextFactory = httpContext;
this.dataContext = dataContext;
}
(...)
Where the DataContxtFactory is simply
public class HttpContextFactory : IHttpContextFactory
{
public HttpContextBase Create()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
And the error is reported exactly in the code above.
Below is my class file which have different names than the one that is used in the project.
public partial class College
{
public List<Students> Students;
}
public partial class Students
{
public List<Activity> Activity;
}
public partial class Activity{
public List<string> Name;
}
Below is my aspx.cs code
College.Students.Add(new Students{ studentno= studentnumber.text});
int index2 = College.Students.FindIndex(c => c.studentno== lineno);
College.Students[index2].Activity= new List<Activity>();
College.Students[index2].Activity.Add(new Activity{ });
int k = (College.Students[index2].Activity.Count) - 1;
College.Students[index2].Activity[k].Name = new List<string>();
string ctrlStr = String.Empty;
foreach (string ctl in Page.Request.Form)
{
if (ctl.Contains("Name"))
{
ctrlStr = ctl.ToString();
College.Students[index2].Activity[k].Name[0] = (Request.Form[ctrlStr]);--- It errors out here...not understanding the reason...Am i missing any line of code
}
Object reference not set to an instance of an object
Change the declaration of the lists in your classes to:
public List<Students> Students = new List<Students>();
By doing simply public List<Students> Students; you're saying that Students exists but not actually setting it up (you're setting it to null) so you can't use any of the methods or properties that come with a List<T> until you initialise it.
Index out of range
This line throws an Index out of range
College.Students[index2].Activity[k].Name[0]
because even though you've newed up Name to a List<string> you haven't added anything to it yet so you're trying to reference a non-existent index. Insetad of that, use:
College.Students[index2].Activity[k].Name.Add((Request.Form[ctrlStr]);
You need to initialize Lists
public partial class College
{
public List<Students> Students = new List<Students>();
}
public partial class Students
{
public List<Activity> Activity = new List<Activity>();
}
public partial class Activity{
public List<string> Name = new List<string>();
}
I have an object called MyObject that has several properties. MyList is a list of MyObject that I populate with a linq query and then I serialize MyList into json. I end up with something like this
List<MyObject> MyList = new List<MyObject>();
MyList = TheLinqQuery(TheParam);
var TheJson = new System.Web.Script.Serialization.JavaScriptSerializer();
string MyJson = TheJson.Serialize(MyList);
What I want to do is serialize only parts of MyObject. For instance, I might have Property1, Property2...Propertyn and I want MyJson to only include Property3, Property5 and Property8.
I thought of a way to do this by creating a new object with only the properties I want and from there create a new list for the serialization. Is this the best way or is there a better/faster way?
Thanks.
// simple dummy object just showing what "MyObject" could potentially be
public class MyObject
{
public String Property1;
public String Property2;
public String Property3;
public String Property4;
public String Property5;
public String Property6;
}
// custom converter that tells the serializer what to do when it sees one of
// the "MyObject" types. Use our custom method instead of reflection and just
// dumping properties.
public class MyObjectConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new ApplicationException("Serializable only");
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
// create a variable we can push the serailized results to
Dictionary<string, object> result = new Dictionary<string, object>();
// grab the instance of the object
MyObject myobj = obj as MyObject;
if (myobj != null)
{
// only serailize the properties we want
result.Add("Property1", myobj.Property1);
result.Add("Property3", myobj.Property3);
result.Add("Property5", myobj.Property5);
}
// return those results
return result;
}
public override IEnumerable<Type> SupportedTypes
{
// let the serializer know we can accept your "MyObject" type.
get { return new Type[] { typeof(MyObject) }; }
}
}
And then where ever you're serializing:
// create an instance of the serializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
// register our new converter so the serializer knows how to handle our custom object
serializer.RegisterConverters(new JavaScriptConverter[] { new MyObjectConverter() });
// and get the results
String result = serializer.Serialize(MyObjectInstance);
I am using DataAnnotations for my model validation i.e.
[Required(ErrorMessage="Please enter a name")]
public string Name { get; set; }
In my controller, I am checking the value of ModelState. This is correctly returning false for invalid model data posted from my view.
However, when executing the unit test of my controller action, ModelState always returns true:
[TestMethod]
public void Submitting_Empty_Shipping_Details_Displays_Default_View_With_Error()
{
// Arrange
CartController controller = new CartController(null, null);
Cart cart = new Cart();
cart.AddItem(new Product(), 1);
// Act
var result = controller.CheckOut(cart, new ShippingDetails() { Name = "" });
// Assert
Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
Assert.IsFalse(result.ViewData.ModelState.IsValid);
}
Do I need to do anything extra to set up the model validation in my tests?
I posted this in my blog post:
using System.ComponentModel.DataAnnotations;
// model class
public class Fiz
{
[Required]
public string Name { get; set; }
[Required]
[RegularExpression(".+#..+")]
public string Email { get; set; }
}
// in test class
[TestMethod]
public void EmailRequired()
{
var fiz = new Fiz
{
Name = "asdf",
Email = null
};
Assert.IsTrue(ValidateModel(fiz).Any(
v => v.MemberNames.Contains("Email") &&
v.ErrorMessage.Contains("required")));
}
private IList<ValidationResult> ValidateModel(object model)
{
var validationResults = new List<ValidationResult>();
var ctx = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, ctx, validationResults, true);
return validationResults;
}
Validation will be performed by the ModelBinder. In the example, you construct the ShippingDetails yourself, which will skip the ModelBinder and thus, validation entirely. Note the difference between input validation and model validation. Input validation is to make sure the user provided some data, given he had the chance to do so. If you provide a form without the associated field, the associated validator won't be invoked.
There have been changes in MVC2 on model validation vs. input validation, so the exact behaviour depends on the version you are using. See http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html for details on this regarding both MVC and MVC 2.
[EDIT] I guess the cleanest solution to this is to call UpdateModel on the Controller manually when testing by providing a custom mock ValueProvider. That should fire validation and set the ModelState correctly.
I was going through http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html, in this post I didn't like the idea of putting the validation tests in controller test and somewhat manual checking in each test that if the validation attribute exists or not. So, below is the helper method and it's usage which I implemented, it works for both EDM (which has metadata attributes, because of the reason we can not apply attributes on auto generated EDM classes) and POCO objects which have ValidationAttributes applied to their properties.
The helper method does not parse into hierarchical objects, but validation can be tested on flat individual objects(Type-level)
class TestsHelper
{
internal static void ValidateObject<T>(T obj)
{
var type = typeof(T);
var meta = type.GetCustomAttributes(false).OfType<MetadataTypeAttribute>().FirstOrDefault();
if (meta != null)
{
type = meta.MetadataClassType;
}
var propertyInfo = type.GetProperties();
foreach (var info in propertyInfo)
{
var attributes = info.GetCustomAttributes(false).OfType<ValidationAttribute>();
foreach (var attribute in attributes)
{
var objPropInfo = obj.GetType().GetProperty(info.Name);
attribute.Validate(objPropInfo.GetValue(obj, null), info.Name);
}
}
}
}
/// <summary>
/// Link EDM class with meta data class
/// </summary>
[MetadataType(typeof(ServiceMetadata))]
public partial class Service
{
}
/// <summary>
/// Meta data class to hold validation attributes for each property
/// </summary>
public class ServiceMetadata
{
/// <summary>
/// Name
/// </summary>
[Required]
[StringLength(1000)]
public object Name { get; set; }
/// <summary>
/// Description
/// </summary>
[Required]
[StringLength(2000)]
public object Description { get; set; }
}
[TestFixture]
public class ServiceModelTests
{
[Test]
[ExpectedException(typeof(ValidationException), ExpectedMessage = "The Name field is required.")]
public void Name_Not_Present()
{
var serv = new Service{Name ="", Description="Test"};
TestsHelper.ValidateObject(serv);
}
[Test]
[ExpectedException(typeof(ValidationException), ExpectedMessage = "The Description field is required.")]
public void Description_Not_Present()
{
var serv = new Service { Name = "Test", Description = string.Empty};
TestsHelper.ValidateObject(serv);
}
}
this is another post http://johan.driessen.se/archive/2009/11/18/testing-dataannotation-based-validation-in-asp.net-mvc.aspx which talks about validating in .Net 4, but i think i am going to stick to my helper method which is valid in both 3.5 and 4
I like to test the data attributes on my models and view models outside the context of the controller. I've done this by writing my own version of TryUpdateModel that doesn't need a controller and can be used to populate a ModelState dictionary.
Here is my TryUpdateModel method (mostly taken from the .NET MVC Controller source code):
private static ModelStateDictionary TryUpdateModel<TModel>(TModel model,
IValueProvider valueProvider) where TModel : class
{
var modelState = new ModelStateDictionary();
var controllerContext = new ControllerContext();
var binder = ModelBinders.Binders.GetBinder(typeof(TModel));
var bindingContext = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
() => model, typeof(TModel)),
ModelState = modelState,
ValueProvider = valueProvider
};
binder.BindModel(controllerContext, bindingContext);
return modelState;
}
This can then be easily used in a unit test like this:
// Arrange
var viewModel = new AddressViewModel();
var addressValues = new FormCollection
{
{"CustomerName", "Richard"}
};
// Act
var modelState = TryUpdateModel(viewModel, addressValues);
// Assert
Assert.False(modelState.IsValid);
I had an issue where TestsHelper worked most of the time but not for validation methods defined by the IValidatableObject interface. The CompareAttribute also gave me some problems. That is why the try/catch is in there. The following code seems to validate all cases:
public static void ValidateUsingReflection<T>(T obj, Controller controller)
{
ValidationContext validationContext = new ValidationContext(obj, null, null);
Type type = typeof(T);
MetadataTypeAttribute meta = type.GetCustomAttributes(false).OfType<MetadataTypeAttribute>().FirstOrDefault();
if (meta != null)
{
type = meta.MetadataClassType;
}
PropertyInfo[] propertyInfo = type.GetProperties();
foreach (PropertyInfo info in propertyInfo)
{
IEnumerable<ValidationAttribute> attributes = info.GetCustomAttributes(false).OfType<ValidationAttribute>();
foreach (ValidationAttribute attribute in attributes)
{
PropertyInfo objPropInfo = obj.GetType().GetProperty(info.Name);
try
{
validationContext.DisplayName = info.Name;
attribute.Validate(objPropInfo.GetValue(obj, null), validationContext);
}
catch (Exception ex)
{
controller.ModelState.AddModelError(info.Name, ex.Message);
}
}
}
IValidatableObject valObj = obj as IValidatableObject;
if (null != valObj)
{
IEnumerable<ValidationResult> results = valObj.Validate(validationContext);
foreach (ValidationResult result in results)
{
string key = result.MemberNames.FirstOrDefault() ?? string.Empty;
controller.ModelState.AddModelError(key, result.ErrorMessage);
}
}
}