I have a record that performs a verification in its constructor as such :
public record Configuration(URI url) {
public Configuration(URI url) {
Validate.httpValid(url, "url");
}
}
Where the httpValid method is :
public static URI httpValid(final URI value, final String property) {
try {
value.toURL();
} catch (IllegalArgumentException | MalformedURLException e) {
throw new InvalidPropertyValueException(property, "httpValid", value, Map.of());
}
return value;
}
This however fails the test i'm trying to create :
#Test
void Should_RespectEqualsContract() {
EqualsVerifier
.forClass(Configuration.class)
.withPrefabValues(
Configuration.class,
new Configuration(URI.create("http://a.com")),
new Configuration(URI.create("http://b.com")))
.verify();
}
This is because EqualsVerifier is trying to create an object with "x" as argument :
InvalidPropertyValueException: The value x is not a valid httpValid as url
You're very close. You shouldn't provide the class that you're testing as a prefab value; instead you need to provide the paramter that's causing trouble, like this:
#Test
void Should_RespectEqualsContract() {
EqualsVerifier
.forClass(Configuration.class)
.withPrefabValues(
URI.class,
URI.create("http://a.com"),
URI.create("http://b.com"))
.verify();
}
Related
I am following following blog to click to call.
https://www.twilio.com/docs/tutorials/click-to-call-java-spring
I am able to place call and record too. But how can we store recording for each channel ?
Can someone please help.?
callCreator.setRecordingChannels("5"); or
callCreator.setRecordingChannels("dual");
does not help
Here is the complete class
public class TwilioLine {
private String twilioNumber;
private TwilioRestClient restClient;
public TwilioLine(TwilioRestClient restClient, String twilioNumber) {
this.restClient = restClient;
this.twilioNumber = twilioNumber;
}
public void call(final String phoneNumber, final String responseUrl) {
try {
CallCreator callCreator = new CallCreator(new PhoneNumber(phoneNumber), new PhoneNumber(twilioNumber), new URI(responseUrl));
callCreator.setRecord(true);
callCreator.setSendDigits("8245719056");
callCreator.setRecordingChannels("5");
callCreator.create(restClient);
} catch (URISyntaxException e) {
throw new CallException(e);
}
}
}
I have a combo box over my GUI in JavaFX.
This Combo Box is composed of a complex type elements :
public class DureeChoiceBoxElement extends ObservableValueBase<DureeChoiceBoxElement> {
private IntegerProperty duree;
#Override
public String toString() {
return duree.get() + " an";
}
}
I want to map (or bind) the selected complex element with my model which contains the simple type :
public class Pel {
private IntegerProperty duree = new SimpleIntegerProperty(1);
public Property<Number> dureeProperty() {
return duree;
}
public void setDuree(Integer duree) {
this.duree.setValue(duree);
}
public Integer getDuree() {
return duree.getValue();
}
}
How to do it ?
I tried in the controller with :
public class PelController {
#FXML
private ChoiceBox<DureeChoiceBoxElement> duree;
//etc..
pel.dureeProperty().bind(createElapsedBindingByBindingsAPI2(duree.getValue()));
/*
* #return an ObjectBinding of immutable TimeElapsed objects for the player
*/
private ObjectBinding<Property<Number>> createElapsedBindingByBindingsAPI2(
final DureeChoiceBoxElement dureeChoiceBoxElement) {
return Bindings.createObjectBinding(new Callable<Property<Number>>() {
#Override
public IntegerProperty call() throws Exception {
return dureeChoiceBoxElement.dureeProperty();
}
}, dureeChoiceBoxElement.dureeProperty());
}
}
But it doesn't work (even not compile). I want to say that "Bind this simple property to this complex Object calling the method I give you through the method named "createElapsedBindingByBindingsAPI2(..)".
It is logical read but I didn't managed to make it works anyway.
That's poor ....
Any help please :).
Example that (obviously) works with legacy code style (Swing coding) :
duree.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<DureeChoiceBoxElement>() {
#Override
public void changed(ObservableValue<? extends DureeChoiceBoxElement> observable,
DureeChoiceBoxElement oldValue, DureeChoiceBoxElement newValue) {
// changement durée
log.debug("Durée sélectionnée : {}", duree.getSelectionModel().getSelectedItem().getDuree());
log.debug("Durée bindée ? : {}", pel.getDuree());
pel.setDuree(duree.getSelectionModel().getSelectedItem().getDuree());
}
});
Like this my model is set to selected item. But it implies some boilerplate code. Any better idea based on high level bindings of JavaFX ?
This question already has answers here:
How to Mock/Stub or simply ignore HttpRequest when unit testing [duplicate]
(2 answers)
Closed 7 years ago.
public class DemoController : Controller
{
private readonly ICommonOperationsRepository _commonRepo;
public DemoController (ICommonOperationsRepository commonRepo)
{
_commonRepo = commonRepo;
}
public ActionResult Default()
{
var model = new DemoModel();
try
{
**ConcreteClass cc = new ConcreteClass(Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString());
cc.ConcreteClassMethod();**
model.ListTopListing.AddRange(_commonRepo.GetListings());
}
catch (Exception ex)
{
ExceptionHandler objErr = new ExceptionHandler(ex, "DemoController .Default()\n Exception : " + ex.Message);
objErr.LogException();
}
return View(model);
}
}
I am trying to unit test my controller. ConcreteClass constructor and its method ConcreteClassMethod both have some dependency on HttpRequest variables which i am not able to pass from my unit tests.
I want a way by which i can simply skip execution of ConcreteClass's constructor and ConcreteClassMethod when I am calling Default action of DemoController.
You can't create a new instance of an object and stop the constructor from being called. You would have to create an empty parameterless constructor.
public class ConcreteClass
{
private string MyString;
// Your constructor
public ConcreteClass(string myString)
{
this.MyString = myString;
}
// Parameterless constructor
public ConcreteClass()
{
// Do nothing, no code
}
// A method that might use MyString
public void DoSomethingWithMyString()
{
var trimmedString = this.MyString.Trim();
}
}
Either that or re-factor the way that your methods work so that it doesn't rely on having a string passed in on the constructor:
public class ConcreteClass
{
// No constructor required anymore
// Pass the string in to the methods that need the string
public void DoSomethingWithMyString(string myString)
{
var trimmedString = myString.Trim();
}
// Pass the string in to the methods that need the string
public void DoSomethingElseWithMyString(string myString)
{
var trimmedString = Int32.Parse(myString);
}
}
However, that probably doesn't solve the problem, bearing in mind that you want to inject your Request variable and you don't have access to them, can't you just do the following:
public class DemoController : Controller
{
private string HttpRewriteUrl;
public DemoController()
{
this.HttpRewriteUrl = Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString();
}
// Custom constructor for unit testing
public DemoController(string httpRewriteUrl)
{
this.HttpRewriteUrl = httpRewriteUrl;
}
public ActionResult Default()
{
// Get the value from the object
ConcreteClass cc = new ConcreteClass(this.HttpRewriteUrl);
cc.ConcreteClassMethod();
}
}
Now within your Unit Tests you can use the second constructor and pass the value in:
var controller = new DemoController("your value to pass in here");
controller.Default();
I have an external dll written in C# and I studied from the assemblies documentation that it writes its debug messages to the Console using Console.WriteLine.
this DLL writes to console during my interaction with the UI of the Application, so i don't make DLL calls directly, but i would capture all console output , so i think i got to intialize in form load , then get that captured text later.
I would like to redirect all the output to a string variable.
I tried Console.SetOut, but its use to redirect to string is not easy.
As it seems like you want to catch the Console output in realtime, I figured out that you might create your own TextWriter implementation that fires an event whenever a Write or WriteLine happens on the Console.
The writer looks like this:
public class ConsoleWriterEventArgs : EventArgs
{
public string Value { get; private set; }
public ConsoleWriterEventArgs(string value)
{
Value = value;
}
}
public class ConsoleWriter : TextWriter
{
public override Encoding Encoding { get { return Encoding.UTF8; } }
public override void Write(string value)
{
if (WriteEvent != null) WriteEvent(this, new ConsoleWriterEventArgs(value));
base.Write(value);
}
public override void WriteLine(string value)
{
if (WriteLineEvent != null) WriteLineEvent(this, new ConsoleWriterEventArgs(value));
base.WriteLine(value);
}
public event EventHandler<ConsoleWriterEventArgs> WriteEvent;
public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent;
}
If it's a WinForm app, you can setup the writer and consume its events in the Program.cs like this:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
using (var consoleWriter = new ConsoleWriter())
{
consoleWriter.WriteEvent += consoleWriter_WriteEvent;
consoleWriter.WriteLineEvent += consoleWriter_WriteLineEvent;
Console.SetOut(consoleWriter);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
static void consoleWriter_WriteLineEvent(object sender, Program.ConsoleWriterEventArgs e)
{
MessageBox.Show(e.Value, "WriteLine");
}
static void consoleWriter_WriteEvent(object sender, Program.ConsoleWriterEventArgs e)
{
MessageBox.Show(e.Value, "Write");
}
It basically amounts to the following:
var originalConsoleOut = Console.Out; // preserve the original stream
using(var writer = new StringWriter())
{
Console.SetOut(writer);
Console.WriteLine("some stuff"); // or make your DLL calls :)
writer.Flush(); // when you're done, make sure everything is written out
var myString = writer.GetStringBuilder().ToString();
}
Console.SetOut(originalConsoleOut); // restore Console.Out
So in your case you'd set this up before making calls to your third-party DLL.
You can also call SetOut with Console.OpenStandardOutput, this will restore the original output stream:
Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
Or you can wrap it up in a helper method that takes some code as an argument run it and returns the string that was printed. Notice how we gracefully handle exceptions.
public string RunCodeReturnConsoleOut(Action code)
{
string result;
var originalConsoleOut = Console.Out;
try
{
using (var writer = new StringWriter())
{
Console.SetOut(writer);
code();
writer.Flush();
result = writer.GetStringBuilder().ToString();
}
return result;
}
finally
{
Console.SetOut(originalConsoleOut);
}
}
Using solutions proposed by #Adam Lear and #Carlo V. Dango I created a helper class:
public sealed class RedirectConsole : IDisposable
{
private readonly Action<string> logFunction;
private readonly TextWriter oldOut = Console.Out;
private readonly StringWriter sw = new StringWriter();
public RedirectConsole(Action<string> logFunction)
{
this.logFunction = logFunction;
Console.SetOut(sw);
}
public void Dispose()
{
Console.SetOut(oldOut);
sw.Flush();
logFunction(sw.ToString());
sw.Dispose();
}
}
which can be used in the following way:
public static void MyWrite(string str)
{
// print console output to Log/Socket/File
}
public static void Main()
{
using(var r = new RedirectConsole(MyWrite)) {
Console.WriteLine("Message 1");
Console.WriteLine("Message 2");
}
// After the using section is finished,
// MyWrite will be called once with a string containing all messages,
// which has been written during the using section,
// separated by new line characters
}
I am trying to write my own protocol handler for a JavaFX application that uses webview to access a single website. What I have done so far
My custom URLStreamHandlerFactory
public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
System.out.println("Protocol: " + protocol);
if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) {
return new MyURLStreamHandler();
} else {
return new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
#Override
public void connect() throws IOException {
}
};
}
};
}
}
}
My custom URLStreamHandler
public class MyURLStreamHandler extends java.net.URLStreamHandler{
protected HttpURLConnection openConnection(URL u){
MyURLConnection q = new MyURLConnection(u);
return q;
}
}
My custom HttpURLConnection
public class MyURLConnection extends HttpURLConnection {
static int defaultPort = 443;
InputStream in;
OutputStream out;
Socket s;
publicMyURLConnection(URL url) {
super(url);
try {
setRequestMethod("POST");
} catch (ProtocolException ex) {
ex.printStackTrace();
}
}
public void setRequestProperty(String name, String value){
super.setRequestProperty(name, value);
System.out.println("Namee: " + name);
System.out.println("Value: " + value);
}
public String getRequestProperty(String name){
System.out.println("GET REQUEST: ");
return super.getRequestProperty(name);
}
public OutputStream getOutputStream() throws IOException {
OutputStream os = super.getOutputStream();
System.out.println("Output: " + os);
return os;
}
public InputStream getInputStream() throws IOException {
InputStream is = super.getInputStream();
System.out.println("INout stream: " + is);
return is;
}
#Override
public void connect() throws IOException {
}
#Override
public void disconnect() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public boolean usingProxy() {
throw new UnsupportedOperationException("Not supported yet.");
}
When I run the application I get the following error althouhg it seems to set some headers
Jul 08, 2013 11:09:04 AM com.sun.webpane.webkit.network.URLLoader doRun
WARNING: Unexpected error
java.net.UnknownServiceException: protocol doesn't support input
at java.net.URLConnection.getInputStream(URLConnection.java:839)
at qmed.QMedURLConnection.getInputStream(MyURLConnection.java:67)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at com.sun.webpane.webkit.network.URLLoader.receiveResponse(URLLoader.java:383)
at com.sun.webpane.webkit.network.URLLoader.doRun(URLLoader.java:142)
at com.sun.webpane.webkit.network.URLLoader.access$000(URLLoader.java:44)
at com.sun.webpane.webkit.network.URLLoader$1.run(URLLoader.java:106)
at com.sun.webpane.webkit.network.URLLoader$1.run(URLLoader.java:103)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.webpane.webkit.network.URLLoader.run(URLLoader.java:103)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
All I want to do is get the response back for a given request and reads its binary data. I want the protocol to behave exactly the same way as the default one and only check the binary data of a given respone. What am I doing wrong?
The application is doing all shorts of URLConnections. Is it correct to use a HTTPURLConnection as my custom URLConnection class when the protocol is http or https and start a default URLStreamHandler when other protocols are used like I am doing in MyURLStreamHandlerFactory? Should I just extend the default URLConnection class in MYURLConnection to handle all protocols the same?
Any help would be much appreciated as this is a project threatening problem
Thank you
It might be that all you are missing is a setDoInput(true) or override getDoInput() and return true (that's what i did).
If that does not help check out my working solution:
MyURLStreamHandlerFactory:
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory
{
public URLStreamHandler createURLStreamHandler(String protocol)
{
if (protocol.equals("myapp"))
{
return new MyURLHandler();
}
return null;
}
}
Register Factory:
URL.setURLStreamHandlerFactory(new MyURLStreamHandlerFactory());
MyURLHandler :
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
public class MyURLHandler extends URLStreamHandler
{
#Override
protected URLConnection openConnection(URL url) throws IOException
{
return new MyURLConnection(url);
}
}
MyURLConnection:
import java.io.*;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
/**
* Register a protocol handler for URLs like this: <code>myapp:///pics/sland.gif</code><br>
*/
public class MyURLConnection extends URLConnection
{
private byte[] data;
#Override
public void connect() throws IOException
{
if (connected)
{
return;
}
loadImage();
connected = true;
}
public String getHeaderField(String name)
{
if ("Content-Type".equalsIgnoreCase(name))
{
return getContentType();
}
else if ("Content-Length".equalsIgnoreCase(name))
{
return "" + getContentLength();
}
return null;
}
public String getContentType()
{
String fileName = getURL().getFile();
String ext = fileName.substring(fileName.lastIndexOf('.'));
return "image/" + ext; // TODO: switch based on file-type
}
public int getContentLength()
{
return data.length;
}
public long getContentLengthLong()
{
return data.length;
}
public boolean getDoInput()
{
return true;
}
public InputStream getInputStream() throws IOException
{
connect();
return new ByteArrayInputStream(data);
}
private void loadImage() throws IOException
{
if (data != null)
{
return;
}
try
{
int timeout = this.getConnectTimeout();
long start = System.currentTimeMillis();
URL url = getURL();
String imgPath = url.toExternalForm();
imgPath = imgPath.startsWith("myapp://") ? imgPath.substring("myapp://".length()) : imgPath.substring("myapp:".length()); // attention: triple '/' is reduced to a single '/'
// this is my own asynchronous image implementation
// instead of this part (including the following loop) you could do your own (synchronous) loading logic
MyImage img = MyApp.getImage(imgPath);
do
{
if (img.isFailed())
{
throw new IOException("Could not load image: " + getURL());
}
else if (!img.hasData())
{
long now = System.currentTimeMillis();
if (now - start > timeout)
{
throw new SocketTimeoutException();
}
Thread.sleep(100);
}
} while (!img.hasData());
data = img.getData();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public OutputStream getOutputStream() throws IOException
{
// this might be unnecessary - the whole method can probably be omitted for our purposes
return new ByteArrayOutputStream();
}
public java.security.Permission getPermission() throws IOException
{
return null; // we need no permissions to access this URL
}
}
Some parts of MyURLConnection might not be necessary for it to work, but like this it works for me.
Usage in JavaFX WebView:
<img src="myapp:///pics/image.png"/>
Note about permissions:
I used an applet with AllPermissions for my test with the above code.
In a Sandbox-Applet this won't work, as the setFactory permission is missing.
This is not directly related to the question asked, but might make the question itself obsolete.
With Java SE 6 Update 10 Java Applets support to access resources on any domain and port which is correctly set up with a crossdomain.xml.
With this the reason to register your own protocol might become obsolete, as you can access all resources that you need.
Another idea is: If you are trying to create a kind of network sniffer, why not directly use a network sniffer/analyzer program designed for such a task?
By activating Logging and Tracing in the Java Control-Panel your Java-Console will print all attempts and executed network calls including those from the WebView.
You can see all HTTP & HTTPS calls and their return-code + cookie data.
You might also see other protocol connections, but probably not any data sent over them.
This applies to Applets in a Browser.
If you need this in a different context maybe there is a way to activate the same options by passing command line parameters.