I'm using JavaFX to create a basic GUI. I have a database created in MySQL to store the data. (DBConnect) (connector/j)
This is my very first attempt at connecting the two, as well as using ResultSets/DBConnect
Currently, I have 3 Classes: my Game class, my GameUI class (main), and my DBConnect class.
I am attempting to Reference the ResultSet in my GameUI class, that was originally declared in Game class.
public class Game {
private static DBConnect dbc;
private static Connection conn;
public ResultSet rs;
int id;
String name;
float price;
String vendor;
int rating;
public Game() {
try {
conn = dbc.connect();
String SQL = "Select * from Person";
rs = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE).executeQuery(SQL);
System.out.println("list result set for record..");
printRs(rs);
} catch(SQLException ignore) {
}
}
My User Defined moveNext() method:
public Game moveNext() {
Game g = new Game();
try {
if(rs.next() == false)
rs.previous();
g.setGameId(rs.getInt("gameId"));
g.setGameName(rs.getString("gameName"));
g.setPrice(rs.getFloat("price"));
g.setVendor(rs.getString("vendor"));
g.setRating(rs.getInt("rating"));
} catch(SQLException e) {
e.printStackTrace();
}
return g;
}
The GameUI class i am trying to reference it in:
public class GameUI extends Application {
private Button firstButton = new Button("First");
private Button createButton = new Button("Create");
private Button updateButton = new Button("Update");
private Button deleteButton = new Button("Delete");
private Button lastButton = new Button("Last");
private Button nextButton = new Button("Next");
private Button prevButton = new Button("Prev");
GridPane grid = new GridPane();
HBox hbox = new HBox(14);
private static DBConnect dbc;
private static Connection conn;
// private static
private Pane initButtons() {
hbox.getChildren().addAll(firstButton, createButton, updateButton, deleteButton, lastButton, nextButton, prevButton);
nextButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
Game.rs.moveNext();
}
});
return hbox;
}
My Question is, can I Reference my ResultSet (Game class) in my nextButton event handler (my GameUI class) OR do I have to declare a new result set?
Is this the right place for my user defined moveNext() method, or should I use next()?
I will post more code on request.
You can pass the result set further, but it is bad practice (See Is it Ok to Pass ResultSet?). From what I see from the code you posted it is mainly an issue with the layering of the different parts of the application, that should be separated:
Database related code belong into one layer. No other layer should directly talk to the DB or handle any DB specific objects. To achieve this the DBConnection class should handle all database related stuff. To pass data from the database to the other layers and vice versa you use a data transfer object (DTO) which is basically an object representation of a specific result set. Usually this boils down to one DTO per database table.
Then you have an intermediate layer, lets call it service layer, which is used to communicate from the UI to the database and do some computation.
On top of that you have the UI layer where your application lives. Here you have to consider which actions belong into that layer and what should better be delegated to the service layer.
Take also a look at this wikipedia article: https://en.wikipedia.org/wiki/Multitier_architecture
Related
I am trying to get a list of models but I can't seem to Query the ApplicationDbContext.I am getting a **No overload for method 'Query' takes 1 arguments.
Here my ApplicationDbContext
private readonly ApplicationDbContext _context;
public DapperController(ApplicationDbContext context)
{
_context = context;
}
and the GetAll method
public List<PoleModel> GetAll()
{
var obj = _context.Query<PoleModel>("Select * from dbo.GRAD").ToList();
return obj;
}
Should I use something other then List? Like IEnumerable or something? I am a bit lost as I've not worked in .NET Core before...
You appear to be trying to use a mix up of Entity Framework and Dapper. You're injecting an ApplicationDbContext, but then trying to query it with Dapper as you would a SqlConnection object instead.
To query the context with EF, you'd do something like:
public List<PoleModel> GetAll()
{
var obj = _context.PoleModelDbSet.ToList();
return obj;
}
Whereas to use Dapper, you'd inject a SqlConnection, something like:
private readonly SqlConnection _connection;
public DapperController(SqlConnection connection)
{
_connection = connection;
}
and query it something like:
public List<PoleModel> GetAll()
{
var obj = _connection.Query<PoleModel>("Select * from dbo.GRAD").ToList();
return obj;
}
You need to enable migrations for your code first database to initialize. Open package manager and type in:
Enable-migrations
Add migration initCreate
Update database
I am creating a sling model which fetched a excel file from the file to read and display data in an AEM component.
#Model(
adaptables = SlingHttpServletRequest.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class OnlineCoursesModel {
#Self
private SlingHttpServletRequest request;
#ValueMapValue
private String filePath;
private List<OnlineCourseDTO> onlineCourses;
#PostConstruct
public void init() {
AssetManager assetManager = request.getResourceResolver().adaptTo(AssetManager.class);
Asset asset = assetManager.getAsset(filePath);
/** Do Something With the Asset **/
}
}
In AEM it's working fine, but when I try to use it with the WCM.io AEM mocking framework, the assetManager is returning null.
#Test
public void checkIfFileIsRead() {
context.load().binaryFile(COURSES_EXCEL_FILE, EXCEL_RESOURCE_PATH);
context.load().json(ONLINE_COURSE_LISTING_AUTHORED, TEST_CONTENT_ROOT);
resource = context.request();
undertest = resource.adaptTo(OnlineCoursesModel.class);
System.out.println(undertest);
}
Your test is a little bit too complicated. Can you please try this simpler version:
#Test
public void checkIfFileIsRead() {
context.create().asset("/content/dam/image.jpg", 1, 1, StandardImageHandler.JPEG_MIMETYPE);
undertest = context.request().adaptTo(OnlineCoursesModel.class);
assertNotNull(undertest);
}
This will create a new asset at /content/dam/image.jpg with a width of 1 and a height of 1 and mime type image/jpg.
You do not need to load a binary and additional json.
Additional notes
You also do not need to adapt from a request. That is considered bad practice and should only be done if you need specific information that is only part of the request. For example information about the user sending the request.
Otherwise, always adapt from Resource.class.
Example:
#Model(adaptables = Resource.class)
public class OnlineCoursesModel {
#OSGiService
private AssetManager assetManager;
#PostConstruct
public void init() {
Asset asset = assetManager.getAsset(filePath);
/** Do Something With the Asset **/
}
}
I'm trying to do the Mockito for a method called generateToken() by using MockitoJUnitRunner.class. The source which I have tried to do as follows.
#RunWith(MockitoJUnitRunner.class)
public class LoginServiceTest {
#Mock
private UserRepository userRepository;
#Mock
private JwtTokenGenerator jwtTokenGenerator;
#InjectMocks
private LoginServiceImpl loginServiceImpl = new LoginServiceImpl();
private JwtUserDto user;
private String jwtSecret;
private String username;
private String password;
/**
* Initialize test data before test cases execution
*/
#Before
public void init() {
user = new JwtUserDto();
user.setId(1L);
user.setUsername("kray1");
user.setRole("Admin");
}
#Test
public void testLogin() {
try {
Mockito.when(jwtTokenGenerator.generateToken(user, jwtSecret)).thenReturn("myToken");
String actual = loginServiceImpl.login(username, password);
assertNotNull(actual);
} catch (Exception e) {
e.printStackTrace();
}
}
For that generateToken() method, I have to pass user object and a string. I'm declaring the user object in Init() method. When I try to execute this, the value return from the login method is null. But when I try to pass the user object as null then it will work as expected. So the problem should be with the user object.
Is there anything, like Mockito is blocking this kind of object with added properties or related thing? Please help to find a way to pass this user object with Mockito.
The LoginServiceImpl class as follows.
public class LoginServiceImpl implements LoginInterface {
#Autowired
private UserRepository userRepository;
#Autowired
private JwtTokenGenerator jwtTokenGenerator;
/*
* (non-Javadoc)
*/
public String login(String userName, String password) {
if (userName != null && password != null && !userName.isEmpty() && !password.isEmpty()) {
List<UserAuthenticationInfo> authInfo = userRepository.findUserRolesByUsernamePassword(userName, password);
if (authInfo != null && !authInfo.isEmpty()) {
JwtUserDto user = new JwtUserDto();
user.setId((long) authInfo.get(0).getUserId());
user.setUsername(userName);
user.setRole(authInfo.get(0).getUserRole());
return jwtTokenGenerator.generateToken(user, jwtSecret);
}
}
return null;
}
}
Do you have equals/hashcode on User class?
What is the result if you setup mock using
Mockito.when(jwtTokenGenerator.generateToken(any(User.class),any(String.class))
.thenReturn("myToken");
explanation:
When setting expectation as
Mockito.when(jwtTokenGenerator.generateToken(user, jwtSecret)).then...
You instruct your mock to act only for given user object. equals method is used for that. So, if your User is missing equals method, then reference equality is used. Two User objects (each crated with separate new User() call will not be equal.
For non-matching parameters in Mockito.when your mock (thenReturn) is not applied. Default value (null) is returned from mock.
Therefore I prefer to setup mocks not for specific arguments and then use Mockito.verify to check if expected interactions with mock took place. That way your tests are more expressive. Actually most of my object have equals/hashode not because of business reasons (I do not put them in collections) but only for testing and comparing using assertEquals.
Side note:
do not catch (Exception e) { e.printStackTrace(); } in test. It is much easier just to declare test method to throw Exception. End result is same (stacktrace printed) but with less code.
You are probably creating a new JwtUserDto() in your production code or getting the user instance from another mock. If you haven't overwritten the equals() method in your JwtUserDto class your 'test' user won't equal the 'production' user.
Make sure that the production and test user are the same instance or that they .equals each other.
so I've been looking for this for a week now and reading though every problem similar but none seemed to ask the same problem as mine exactly(try reverse engineering other solution similar to what I want with no success.
explained caveman style: I'm trying to create list using Metadata.
I open with a multi dialog and select more than one mp3
I put the file in an ArrayList<File>
I loop though the files with an enhanced for loop and extract metadata using a media variable
The info for the metadata ( like "artist") is what i want to save in an ArrayList for example
the problem is that the listener only works way after the enhanced loop has finished which results in
ArrayList<String> having one object with nothing in it
here is a sample:
ArrayList<String> al;
String path;
public void open(){
files=chooser.showOpenMultipleDialog(new Stage());
for( File f:files){
path=f.getPath();
Media media = new Media("file:/"+path.replace("\\", "/").replace(" ", "%20"));
al= new ArrayList<String>();
media.getMetadata().addListener(new MapChangeListener<String, Object>() {
public void onChanged(Change<? extends String, ? extends Object> change) {
if (change.wasAdded()) {
if (change.getKey().equals("artist")) {
al.add((String) change.getValueAdded());
}
}
}
});
}//close for loop
//then i want to see the size of al like this
system.out.println(al.size());
//then it returns 1 no matter how much file i selected
//when i system out "al" i get an empty string
the other way to read a media source metadata with adding a listener is extract that information in the mediaplayer .setOnReady(); here is an example part of the java controller class
public class uiController implements Initializable {
#FXML private Label label;
#FXML private ListView<String> lv;
#FXML private AnchorPane root;
#FXML private Button button;
private ObservableList<String> ol= FXCollections.observableArrayList();
private List<File> selectedFiles;
private final Object obj= new Object();
#Override
public void initialize(URL url, ResourceBundle rb) {
assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'ui.fxml'.";
assert label != null : "fx:id=\"label\" was not injected: check your FXML file 'ui.fxml'.";
assert lv != null : "fx:id=\"lv\" was not injected: check your FXML file 'ui.fxml'.";
assert root != null : "fx:id=\"root\" was not injected: check your FXML file 'ui.fxml'.";
// initialize your logic here: all #FXML variables will have been injected
lv.setItems(ol);
}
#FXML private void open(ActionEvent event) {
FileChooser.ExtensionFilter extention= new FileChooser.ExtensionFilter("Music Files", "*.mp3","*.m4a","*.aif","*.wav","*.m3u","*.m3u8");
FileChooser fc= new FileChooser();
fc.setInitialDirectory(new File(System.getenv("userprofile")));
fc.setTitle("Select File(s)");
fc.getExtensionFilters().add(extention);
selectedFiles =fc.showOpenMultipleDialog(root.getScene().getWindow());
if(selectedFiles != null &&!selectedFiles.isEmpty()){
listFiles();
}
}
/**
* Convert each fie selected to its URI
*/
private void listFiles(){
try {
for (File file : selectedFiles) {
readMetaData(file.toURI().toString());
synchronized(obj){
obj.wait(100);
}
}
} catch (InterruptedException ex) {
}
System.gc();
}
/**
* Read a Media source metadata
* Note: Sometimes the was unable to extract the metadata especially when
* i have selected large number of files reasons i don't known why
* #param mediaURI Media file URI
*/
private void readMetaData(String mediaURI){
final MediaPlayer mp= new MediaPlayer(new Media(mediaURI));
mp.setOnReady(new Runnable() {
#Override
public void run() {
String artistName=(String) mp.getMedia().getMetadata().get("artist");
ol.add(artistName);
synchronized(obj){//this is required since mp.setOnReady creates a new thread and our loopp in the main thread
obj.notify();// the loop has to wait unitl we are able to get the media metadata thats why use .wait() and .notify() to synce the two threads(main thread and MediaPlayer thread)
}
}
});
}
}
the few changes that have made is used an ObservableList to store the artist name from the metadata
in the code you will find this
synchronized(obj){
obj.wait(100);
}
I do this because the mediaplayer .setOnReady() creates a new thread and the loop is in the main application thread, The loop has to wait for some time before the other thread is created and we are able to extract the metadata, and in the .setOnReady() there is a
synchronized(obj){
obj.notify;
}
to wake up the main thread hence the loop is able to move to the next item
I admit that this may not be the best solution to do this but am welcomed to anyone who has any better way on how to read JavaFx media metadata from a list of files
The full Netbeans project can be found here https://docs.google.com/file/d/0BxDEmOcXqnCLSTFHbTVFcGIzT1E/edit?usp=sharing
plus have created a small MediaPlayer Application using JavaFX which expolits use of the metadata https://docs.google.com/file/d/0BxDEmOcXqnCLR1Z0VGN4ZlJkbUU/edit?usp=sharing
You can use the following function to retrieve the metadata for a given Media object:
public static void initializeMetaData(Media media) {
final Ref<Boolean> ready = new Ref<>(false);
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnReady(() -> {
synchronized (ready) {
ready.set(false);
ready.notify();
}
});
synchronized (ready) {
if (!ready.get()) {
try {
ready.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
However, do not call initializeMetaData from a JavaFX thread, otherwise the thread runs into a deadlock.
PS: It's really ridiculous that one has to build such a workaround. I hope that in future Media will provide an initialize() method which does this job.
My solution to that issue was this:
public class MediaListener implements MapChangeListener<String, Object>
{
public String title = null;
public String artist = null;
public String album = null;
private final Consumer<MediaListener> handler;
private boolean handled = false;
public MediaListener(Consumer<MediaListener> handler)
{
this.handler = handler;
}
#Override
public void onChanged(MapChangeListener.Change<? extends String, ?> ch)
{
if (ch.wasAdded())
{
String key = ch.getKey();
switch (key)
{
case "title":
title = (String) ch.getValueAdded();
break;
case "artist":
artist = (String) ch.getValueAdded();
break;
case "album":
album = (String) ch.getValueAdded();
break;
}
if (!handled && title != null && artist != null && album != null)
{
handler.accept(this);
handled = true;
}
}
}
}
It may not be the best way but it's way cleaner than creating a new MediaPlayer per file.
Example usage:
Media media = Util.createMedia(path);
media.getMetadata().addListener(new MediaListener((data) ->
{
// Use the data object to access the media
}));
Can anyone tell me how to find available agent containers through java code? I am using the JADE agent framework and I have figured out how to create new containers but not find existing containers (so that agents can be deployed in them).
There are two ways of doing this, depending on whether you want to receive the information via an ongoing service or the current snapshot in a message.
To get a snapshot of the IDs of the currently available agent containers, send a Request message to the Agent Management Service (AMS) and wait for its reply. Using the JADE Management Ontology and the QueryPlatformLocationsAction term, the sending and receiving methods would be:
private void queryAMS() throws CodecException, OntologyException {
QueryPlatformLocationsAction query = new QueryPlatformLocationsAction();
Action action = new Action(myAgent.getAID(), query);
ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
message.addReceiver(myAgent.getAMS());
message.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
message.setOntology(JADEManagementOntology.getInstance().getName());
myAgent.getContentManager().fillContent(message, action);
myAgent.send(message);
}
private void listenForAMSReply() throws UngroundedException, CodecException,
OntologyException {
ACLMessage receivedMessage = myAgent.blockingReceive(MessageTemplate
.MatchSender(myAgent.getAMS()));
ContentElement content = myAgent.getContentManager().extractContent(
receivedMessage);
// received message is a Result object, whose Value field is a List of
// ContainerIDs
Result result = (Result) content;
List listOfPlatforms = (List) result.getValue();
// use it
Iterator iter = listOfPlatforms.iterator();
while (iter.hasNext()) {
ContainerID next = (ContainerID) iter.next();
System.out.println(next.getID());
}
}
To get this information as an ongoing service, and to receive the ContainerID of each container as it registers with the AMS, create a Behaviour that extends the AMSSubscriber. Register a handler for the AddedContainer event and you will be able to access the ContainerID of the newly available container:
public class AMSListenerBehaviour extends AMSSubscriber {
#Override
public void installHandlers(Map handlersTable) {
handlersTable.put(AddedContainer.NAME, addedContainerHandler);
}
public final class AddedContainerHandler implements EventHandler {
#Override
public void handle(Event ev) {
AddedContainer event = (AddedContainer) ev;
ContainerID addedContainer = event.getContainer();
System.out.println(addedContainer.getID());
}
Hope this helps,
Russ