DAO initialising integer to 0 when loading - java

When my system loads the text file with the data already in it,it always initialises the integers for restaurantTables and restaurantSeats to 0? How do I stop this from happening and keep the figures assigned when adding to the system?
Here is the code which changes it back to 0:
public class TextRestaurantDAO extends RestaurantDAO {
static final char DELIMITER=':';
#Override
public List<Restaurant> loadRestaurants(Path path) {
List<Restaurant> restaurants = new ArrayList<>();
try (Scanner s = new Scanner(new BufferedReader(new FileReader(path.toString())))) {
s.useDelimiter(Character.toString(DELIMITER));
Restaurant r;
int restaurantId, restaurantTables, restaurantSeats;
String restaurantName, restaurantLocation;
while (s.hasNext()) {
if (s.hasNextInt()) {
restaurantId = s.nextInt();
}
else {
restaurantId = 0;
}
if (s.hasNextInt()) {
restaurantTables = s.nextInt();
}
else {
restaurantTables = 0;
}
if (s.hasNextInt()) {
restaurantSeats = s.nextInt();
}
else {
restaurantSeats = 0;
}
restaurantName = s.next();
restaurantLocation = s.next();
s.nextLine();
r = new Restaurant(restaurantId, restaurantName, restaurantLocation, restaurantTables, restaurantSeats);
restaurants.add(r);
}
s.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(TextCustomerDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return restaurants;
}
#Override
public void storeRestaurants(Path path, List<Restaurant> restaurants) {
try (PrintWriter output = new PrintWriter(path.toFile())) {
for (Restaurant r:restaurants) {
output.println(toFileString(r));
}
output.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(TextRestaurantDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String toFileString(Restaurant r) {
return Integer.toString(r.getRestaurantId()) + DELIMITER +
r.getRestaurantName() + DELIMITER +
r.getRestaurantLocation() + DELIMITER +
r.getRestaurantTables() + DELIMITER +
r.getRestaurantSeats() + DELIMITER;
}
}
If you could help it would be much appreciated.
Here is an example of what the text file has before it loads:
1:Riva:Bothwell:31:78:
After it Loads:
1:Riva:Bothwell:0:0:
How do i stop this from happening?
Thankyou
if you require more code please ask

Related

Print To File in Java

i have a problem in my java exercise.
i need to print a multiply contact information to a file, but when i print more then 1 contact, only 1 contact is displayed in the file..
i tried to debug that but i cant find any mistake
i will put the code of my classes here:
This is Demo Class which i run the code from
public class Demo {
public static void main(String[] args) {
System.out.println("Insert number of Contacts:");
Scanner scanner = new Scanner(System.in);
int val = scanner.nextInt();
Contact[] contacts = new Contact[val];
for(int i = 0 ; i < val; i++) {
System.out.println("Contact #"+(i+1));
System.out.print("Owner: \n");
String owner = scanner.next();
System.out.print("Phone number: \n");
String phoneNum = scanner.next();
System.out.print("Please Select Group:\n"
+ "1 For FRIENDS,\n" +
"2 For FAMILY,\n" +
"3 For WORK,\n" +
"4 For OTHERS");
int enumNum = scanner.nextInt();
Group group;
switch(enumNum) {
case 1:
group=Group.FRIENDS;
break;
case 2:
group=Group.FAMILY;
break;
case 3:
group=Group.WORK;
break;
default:
group=Group.OTHERS;
}//switch end
contacts[i] = new Contact(owner,phoneNum,group);
}//loop end
System.out.println("Insert File name");
String fileName = scanner.next();
File f=null;
for(int i = 0 ; i < val; i++) {
if(i==0) {
f = new File(fileName);
contacts[0].Save(fileName);
}
else {
contacts[i].Save(f);
}
}
}
}
This is Contact Class:
enum Group {
FRIENDS,
FAMILY,
WORK,
OTHERS
};
public class Contact {
private String phoneNumber,owner;
private Group group;
PrintWriter pw = null;
public Contact(String owner ,String phoneNumber,Group group) {
setPhoneNumber(phoneNumber);
setOwner(owner);
setGroup(group);
}
public Contact(String fileName) {
File file = new File(fileName+".txt");
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public Contact(File file) {
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
if(f.createNewFile()) {
System.out.println("File created");
pw = new PrintWriter(f); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
}
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}
public void Save(File f) {
PrintWriter pw=null;
try {
pw = new PrintWriter(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.println(phoneNumber+"\n"+owner+"\n"+group);
pw.close();
}
public String toString() {
return phoneNumber+"\n"+owner+"\n"+group;
}
}
Every time you create PrintWriter the file is being overwritten. Since you create a new PrintWriter for each contact, the file contains only the last contact information. What you should do is to create PrintWriter only once and use it for all contacts.
Firstly, let's create a new save method with such signature:
public void save(PrintWriter writer)
I have also used the lowercase name of the method due to Java naming convention.
Now the implementation of save method will look like this:
writer.println(phoneNumber);
writer.println(owner);
writer.println(group + "\n\n\n");
Then we should replace the usage of Save method with the new one. Here is your code:
String fileName = scanner.next();
File f = null;
for (int i = 0; i < val; i++) {
if(i == 0) {
f = new File(fileName);
contacts[0].Save(fileName);
} else {
contacts[i].Save(f);
}
}
In order to fix the issue we can change it like this:
String fileName = scanner.next();
File file = new File(fileName);
try (PrintWriter writer = new PrintWriter(file)) {
for (int i = 0; i < val; i++) {
contacts[i].save(writer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
I have also used try-with-resources which closes the PrintWriter automatically.
From the Javadoc of the constructor of PrintWriter:
public PrintWriter​(File file)
Parameters: file - The file to use as the destination of this writer. If the file exists then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.
In the Save function you create a PrintWriter everytime. So everytime the file is truncated, and then you lose the contact you saved before.
Since File I/O classes in java use Decorator Design pattern, you can use a FileWriter to take advantage of appending to a file. So you can use this code for Save() method :
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
//System.out.println("File created"); You don't need to create new file.
FileWriter fw=new FileWriter(f,true):// second argument enables append mode
pw = new PrintWriter(fw); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}

PrintWriter printing "line.separator" twice in file

I have a method called saveAgendaDataArrayList() which is suposed to save the data from an ArrayList in a TXT file as following.
public void saveAgendaDataArrayList(String path, ArrayList<Contact> agendaDataArrayList) {
try {
if(agendaDataArrayList!=null) {
File file = new File(path);
PrintWriter p = new PrintWriter(file);
int count = agendaDataArrayList.size();
for(int i=0; i<count; i++) {
Contact temp = new Contact();
temp = agendaDataArrayList.get(i);
p.println(temp.getIdAdress()+";"+temp.getContactType()+";"+temp.getName()+";"+temp.getBirthdayDay()+
";"+temp.getBirthdayMonth()+";"+temp.getBirthdayYear()+";"+temp.getTel1()+";"+temp.getTel2()+
";"+temp.getNeigborhood()+";"+temp.getAddress()+";"+temp.getCep()+";"+temp.getEmail()
+";"+temp.getOtherInformation()+";"+temp.getCreationDate()+";");
}
p.close();
} else {
File file = new File(path);
PrintWriter p = new PrintWriter(file);
p.print("empty agenda");
p.close();
}
} catch (IOException e) {
e.printStackTrace();
}
However, when it runs, I have some new lines coming from I don't know where. Look below.
1;1;Guilhermee;00;00;;8666666;;sem bairro;;;;;12-09-2019 04:45:47;
2;1;Gabriella;00;00;;;;Morada do Sol;;;;;12-09-2019 04:45:57;
3;1;joao;00;00;;;;sem bairro;;;;;12-09-2019 05:38:13;
4;1;lua;00;00;;;;sem bairro;;;;;12-09-2019 06:11:15;
5;1;roberto;00;00;;;;sem bairro;;;;;12-09-2019 06:12:22;
6;1;joquina;00;00;;;;Monte Verde;;;;;12-09-2019 07:38:30;
7;1;luan silva;00;00;;;;sem bairro;;;;;12-09-2019 07:40:07;
8;1;manoel;00;00;;89898989;;sem bairro;asdasd;;;;12-09-2019 07:44:44;
9;1;joana;19;01;1954;;;Cidade Jardim;;;;;12-09-2019 07:48:03;
10;1;mariana;00;00;;;;sem bairro;;;;;12-09-2019 07:57:43;
11;1;agoradeucerto;00;00;;;;Morros;;;;;12-09-2019 08:01:46;
12;1;mais uma tentativa;00;00;;;;sem bairro;;;;;12-09-2019 08:43:19;
I'd like to have an output file as above, but without the empty lines.
I tried to see if the same would happen in console with the method System.out.println(), and it happened there too.
Looking in a text file editor, the Notepad, I noticed there are some LF mixed with CR LF in the end of lines.
I've reviewed the Contact class and all seems to be right.
So, what could I do to reach that result and avoid those empty lines, and why only the last line is in the correct place?
Thank you for your time.
EDIT 1 - The input method
Here is the input method. There are 2 ways to add the data into agendaDataArrayList. The first one is through reading a txt file (1st method) and the second one, through an input interface (2nd method).
1st method
public ArrayList<Contact> getAgendaDataArrayList(String path) {
try {
FileReader reader = new FileReader(path);
Scanner scanner1 = new Scanner(reader);
scanner1.useDelimiter("\r\n|\n");
int count = 0;
while(scanner1.hasNext()) {
scanner1.next();
count++;
}
System.out.println(count);
scanner1.close();
reader.close();
ArrayList<Contact> agendaDataArrayList = new ArrayList<Contact>();
FileReader reader2 = new FileReader(path);
Scanner scanner2 = new Scanner(reader2);
scanner2.useDelimiter(";");
for(int i=0; i<count; i++) {
Contact temp = new Contact();
temp.setIdAdress(scanner2.next()); //[0] id
temp.setContactType(scanner2.next()); //[1] type
temp.setName(scanner2.next()); //[2] name
temp.setBirthdayDay(scanner2.next()); //[3] birthdayDay
temp.setBirthdayMonth(scanner2.next()); //[4] birthdayMonth
temp.setBirthdayYear(scanner2.next()); //[5] birthdayYear
temp.setTel1(scanner2.next()); //[6] tel1
temp.setTel2(scanner2.next()); //[7] tel2
temp.setNeigborhood(scanner2.next()); //[8] neighborhood
temp.setAddress(scanner2.next()); //[9] address
temp.setCep(scanner2.next()); //[10] cep
temp.setEmail(scanner2.next()); //[11] email
temp.setOtherInformation(scanner2.next()); //[12] other information
temp.setCreationDate(scanner2.next()); //[13] creation date
agendaDataArrayList.add(temp);
}
scanner2.close();
reader2.close();
return agendaDataArrayList;
} catch (IOException e) {
e.printStackTrace();
ArrayList<Contact> agendaDataArrayList = new ArrayList<Contact>();
return agendaDataArrayList;
}
}
2nd method
public void saveActionButton() {
Date creationDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Contact newContact = new Contact();
newContact.setIdAdress(mainApp.getNextIdAddress());
if(typeChoiceBox.getValue()==null) {
newContact.setContactType("1");
} else {
newContact.setContactType(typeChoiceBox.getValue());
}
if(nameTextField.getText()==null) {
newContact.setName("sem nome");
} else {
newContact.setName(nameTextField.getText());
}
if(dayChoiceBox.getValue()==null) {
newContact.setBirthdayDay("00");
}else {
newContact.setBirthdayDay(dayChoiceBox.getValue());
}
if(monthChoiceBox.getValue()==null) {
newContact.setBirthdayMonth("00");
}else {
newContact.setBirthdayMonth(monthChoiceBox.getValue());
}
if(yearTextField.getText()==null) {
newContact.setBirthdayYear("0000");
}else {
newContact.setBirthdayYear(yearTextField.getText());
}
if(tel1TextField.getText()==null) {
newContact.setTel1("sem número");
}else {
newContact.setTel1(tel1TextField.getText());
}
if(tel2TextField.getText()==null) {
newContact.setTel2("sem número");
}else {
newContact.setTel2(tel2TextField.getText());
}
if(neighborhoodChoiceBox.getValue()==null) {
newContact.setNeigborhood("sem bairro");
} else {
newContact.setNeigborhood(neighborhoodChoiceBox.getValue());
}
if(addressTextField.getText()==null) {
newContact.setAddress("sem endereço");
} else {
newContact.setAddress(addressTextField.getText());
}
if(cepTextField.getText()==null) {
newContact.setCep("sem CEP");
}else {
newContact.setCep(cepTextField.getText());
}
if(emailTextField.getText()==null) {
newContact.setEmail("sem e-mail");
} else {
newContact.setEmail(emailTextField.getText());
}
if(otherInfoTextArea.getText()==null) {
newContact.setOtherInformation("sem mais informações");
}else {
newContact.setOtherInformation(otherInfoTextArea.getText());
}
newContact.setCreationDate(formatter.format(creationDate).toString());
mainApp.addContactToAgendaDataArrayList(newContact);
mainApp.refreshFullContentInMainLayout();
mainApp.saveFile();
Stage stage = (Stage) saveButton.getScene().getWindow();
stage.close();
}
}
Compare the first method output of the entries with id address 12 and the other ones that have new lines before them.
It is possible that some data are inserted on windows (therefore the CR LF whitespaces) and some on the unix system (which uses only LF). Anyway, it seems tha data itself contains new line marks, the PrinterWriter works as you would like.
A small test:
import java.util.ArrayList;
import java.io.*;
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
ArrayList<Contact> list = new ArrayList<>();
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
list.add(new Contact());
try {
File file = new File("output.txt");
PrintWriter p = new PrintWriter(file);
int count = list.size();
for (int i = 0; i < count; i++) {
Contact temp = list.get(i);
p.println(temp.getFavColour() + ";" + temp.getSurname() + ";" + temp.getName() + ";");
}
p.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static class Contact {
public String getName() {
return "John";
}
public String getSurname() {
return "Black";
}
public String getFavColour() {
return "red";
}
}
}

String[] cannot be converted to State[]

Just wondering what I have done wrong here I'm getting an error in the method setLine() which is:
error: incompatible types: String[] cannot be converted to State[]
Im not too sure on what to do to fix it since I need the line to be split and stored in that state array so I can determine whether if it is a state or location when reading from a csv file.
public static void readFile(String inFilename)
{
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int stateCount = 0, locationCount = 0;
String line;
try
{
fileStrm = new FileInputStream(inFilename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
line = bufRdr.readLine();
while (line != null)
{
if (line.startsWith("STATE"))
{
stateCount++;
}
else if (line.startsWith("LOCATION"))
{
locationCount++;
}
line = bufRdr.readLine();
}
fileStrm.close();
State[] state = new State[stateCount];
Location[] location = new Location[locationCount];
}
catch (IOException e)
{
if (fileStrm != null)
{
try { fileStrm.close(); } catch (IOException ex2) { }
}
System.out.println("Error in file processing: " + e.getMessage());
}
}
public static void processLine(String csvRow)
{
String thisToken = null;
StringTokenizer strTok;
strTok = new StringTokenizer(csvRow, ":");
while (strTok.hasMoreTokens())
{
thisToken = strTok.nextToken();
System.out.print(thisToken + " ");
}
System.out.println("");
}
public static void setLine(State[] state, Location[] location, int stateCount, int locationCount, String line)
{
int i;
state = new State[stateCount];
state = line.split("="); <--- ERROR
for( i = 0; i < stateCount; i++)
{
}
}
public static void writeOneRow(String inFilename)
{
FileOutputStream fileStrm = null;
PrintWriter pw;
try
{
fileStrm = new FileOutputStream(inFilename);
pw = new PrintWriter(fileStrm);
pw.println();
pw.close();
}
catch (IOException e)
{
if (fileStrm != null)
{
try
{
fileStrm.close();
}
catch (IOException ex2)
{}
}
System.out.println("Error in writing to file: " + e.getMessage());
}
}
This error occurs, as it just says 'String[] cannot be converted to State[]'. That is like you wanted to store an Integer into a String, it's the same, because the types don't have a relation to each other (parent -> child).
So if you want to solve your problem you need a method which converts the String[] into a State[]. Something like this:
private State[] toStateArray(String[] strings){
final State[] states = new State[strings.length];
for(int i = strings.length-1; i >= 0; i--){
states[i] = new State(strings[i]); // here you have to decide how to convert String to State
}
return states;
}

How to get variables from exception code block

I want to get user1.name variable from public static void FileRead()to private void jButton1ActionPerformed but It doesn't read user1.name. Can you explain me how can I use that variable.
public static class Users {
public String name;
public String password;
Users(String name1, String password1) {
name = name1;
password = password1;
}
}
public static void FileRead() {
try {
BufferedReader in = new BufferedReader(new FileReader("C:/Users/B_Ali/Documents/NetBeansProjects/JavaApplication20/UserNamePassword.txt"));
String[] s1 = new String[5];
String[] s2 = new String[5];
int i = 0;
while ((s1[i] = in.readLine()) != null) {
s1[i] = s2[i];
i = i + 1;
if (i == 1) {
Users user1 = new Users(s2[0], s2[1]);
}
else if (i == 3) {
Users user2 = new Users(s2[2], s2[3]);
}
else if (i == 5) {
Users user3 = new Users(s2[4], s2[5]);
}
}
in.close();
}
catch (FileNotFoundException ex) {
Logger.getLogger(LoginScreen.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(LoginScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JOptionPane.showMessageDialog(null, user1.name);
// TODO add your handling code here:
}
where should I declare it?
Edit: if i declare it as you said before. It becomes meaningless because i want to use user1.name which is defined in FileRead().
Declare it global.
Users user1;
public static class Users {
public String name;
public String password;
Users(String name1, String password1) {
name = name1;
password = password1;
}
public String getName()
{ return this.name;
}
public String getPassword()
{return this.password;
}
}
Users user1, user2;
public static void FileRead() {
try {
BufferedReader in = new BufferedReader(new FileReader("C:/Users/B_Ali/Documents/NetBeansProjects/JavaApplication20/UserNamePassword.txt"));
String[] s1 = new String[5];
String[] s2 = new String[5];
int i = 0;
while ((s1[i] = in.readLine()) != null) {
s1[i] = s2[i];
i = i + 1;
if (i == 1) {
Users user1 = new Users(s2[0], s2[1]);
}
else if (i == 3) {
Users user2 = new Users(s2[2], s2[3]);
}
else if (i == 5) {
Users user3 = new Users(s2[4], s2[5]);
}
}
in.close();
}
catch (FileNotFoundException ex) {
Logger.getLogger(LoginScreen.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(LoginScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JOptionPane.showMessageDialog(null, user1.getName());
// TODO add your handling code here:
}
You need to declare the variables you need outside of the try clause like:
String global = null;
try{
global = "abc";
throw new Exception();
}
catch(Exception e){
if (global != null){
//your code
}
}

OrientDB slow when browsing cluster

Well what i am trying to achieve is to save pairs of words in a sentence and if the word is already there , i am trying to save a list of words against one.
To save the pairing as there could many millions as my data set file is very large , i opted for orientdb. I dont know if i am approaching it correctly but orientdb is very slow. After 8 hours of running it has only made pairs for 12000 sentences.
As far as i have checked the major slowdown was in browsing cluster.
Attached is my code, please if ant one can give any pointers over my approach.
public static void main(String[] args) {
// TODO Auto-generated method stub
Main m = new Main();
m.openDatabase();
m.readFile("train_v2.txt");
m.closeDatabase();
}
}
class Main {
ODatabaseDocumentTx db;
Map<String, Object> index;
List<Object> list = null;
String pairing[];
ODocument doc;
Main() {
}
public void closeDatabase() {
if (!db.isClosed()) {
db.close();
}
}
void openDatabase() {
db = new ODatabaseDocumentTx("local:/databases/model").open("admin",
"admin");
doc = new ODocument("final");
}
public void readFile(String filename) {
InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
int i = 1;
BufferedReader br = null; // buffered for readLine()
try {
String s;
ins = new FileInputStream(filename);
r = new InputStreamReader(ins, "UTF-8"); // leave charset out
// for
// default
br = new BufferedReader(r);
while ((s = br.readLine()) != null) {
System.out.println("" + i);
createTermPair(s.replaceAll("[^\\w ]", "").trim());
i++;
}
} catch (Exception e) {
System.err.println(e.getMessage()); // handle exception
} finally {
closeDatabase();
if (br != null) {
try {
br.close();
} catch (Throwable t) { /* ensure close happens */
}
}
if (r != null) {
try {
r.close();
} catch (Throwable t) { /* ensure close happens */
}
}
if (ins != null) {
try {
ins.close();
} catch (Throwable t) { /* ensure close happens */
}
}
}
}
private void createTermPair(String phrase) {
phrase = phrase + " .";
String[] word = phrase.split(" ");
for (int i = 0; i < word.length - 1; i++) {
if (!word[i].trim().equalsIgnoreCase("")
&& !word[i + 1].trim().equalsIgnoreCase("")) {
String wordFirst = word[i].toLowerCase().trim();
String wordSecond = word[i + 1].toLowerCase().trim();
String pair = wordFirst + " " + wordSecond;
checkForPairAndWrite(pair);
}
}
}
private void checkForPairAndWrite(String pair) {
try {
pairing = pair.trim().split(" ");
if (!pairing[1].equalsIgnoreCase(" ")) {
index = new HashMap<String, Object>();
for (ODocument docr : db.browseCluster("final")) {
list = docr.field(pairing[0]);
}
if (list == null) {
list = new ArrayList<>();
}
list.add("" + pairing[1]);
if (list.size() >= 1)
index.put(pairing[0], list);
doc.fields(index);
doc.save();
}// for (int i = 0; i < list.size(); i++) {
// System.out.println("" + list.get(i));
// }
} catch (Exception e) {
}
return;
}
}

Categories

Resources