0

I'm trying to load data from "feedsfile" in the parameter and return it as a List. So far I tried it with a Scanner by adding "feedsfile" to the List "loadFeed" with the .add method, but it doesn't seem to work.

It says:"The method add(Feed) in the type List is not applicable for the arguments (File)".

@Override
public List<Feed> loadSubscribedFeeds(File feedsFile) {
    List<Feed> loadFeed = new ArrayList<>();
    
    try (Scanner s = new Scanner(new FileReader(feedsFile))) {
        while (s.hasNext()) {
            loadFeed.add(feedsFile);
        }
    } 
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return loadFeed;
}

Here's the Feed Class

package de.uk.java.feader.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.rometools.rome.feed.synd.SyndEntry;
import com.rometools.rome.feed.synd.SyndFeed;

import de.uk.java.feader.utils.FeaderUtils;

public class Feed implements Serializable, Comparable<Feed> {

private static final long serialVersionUID = 1L;

private String url;
private String title;
private String description;
private String publishedDateString;
private List<Entry> entries;


public Feed(String url) {
    super();
    this.url = url;
    this.entries = new ArrayList<Entry>();
    this.title = "";
    this.description = "";
    this.publishedDateString = "";
}

/**
 * Creates an instance of a Feed and transfers the feed
 * data form a SyndFeed object to the new instance.
 * @param url The URL string of this feed
 * @param sourceFeed The SyndFeed object holding the data for this feed instance
 */
public Feed(String url, SyndFeed sourceFeed) {
    this(url);
    setTitle(sourceFeed.getTitle());
    setDescription(sourceFeed.getDescription());
    
    if (sourceFeed.getPublishedDate() != null)
        setPublishedDateString(FeaderUtils.DATE_FORMAT.format(sourceFeed.getPublishedDate()));

    
    for (SyndEntry entryTemp : sourceFeed.getEntries()) {
        Entry entry = new Entry(entryTemp.getTitle());
        entry.setContent(entryTemp.getDescription().getValue());
        entry.setLinkUrl(entryTemp.getLink());
        entry.setParentFeedTitle(getTitle());
        if (entryTemp.getPublishedDate() != null) {
            entry.setPublishedDateString(FeaderUtils.DATE_FORMAT.format(entryTemp.getPublishedDate()));
        }
        addEntry(entry);
    }
}

public String getUrl() {
    return url;
}

public void setTitle(String title) {
    this.title = title != null ? title : "";
}

public String getTitle() {
    return title;
}

public void setDescription(String description) {
    this.description = description != null ? description : "";
}

public String getDescription() {
    return description;
}

public void setPublishedDateString(String publishedDateString) {
    this.publishedDateString = publishedDateString != null ? publishedDateString : "";
}

public String getPublishedDateString() {
    return publishedDateString;
}

/**
 * Returns a short string containing a combination of meta data for this feed
 * @return info string
 */
public String getShortFeedInfo() {
    return getTitle() + " [" +
            getEntriesCount() + " entries]: " + 
            getDescription() +
            (getPublishedDateString() != null && getPublishedDateString().length() > 0
                ? " (updated " + getPublishedDateString() + ")"
                : "");
}

public void addEntry(Entry entry) {
    if (entry != null) entries.add(entry);
}

public List<Entry> getEntries() {
    return entries;
}

public int getEntriesCount() {
    return entries.size();
}

@Override
public boolean equals(Object obj) {
    return (obj instanceof Feed)
        && ((Feed)obj).getUrl().equals(url);
}

@Override
public int hashCode() {
    return url.hashCode();
}

@Override
public String toString() {
    return getTitle();
}

@Override
public int compareTo(Feed o) {
    return getPublishedDateString().compareTo(o.getPublishedDateString());
}

}

TotalNoob
  • 13
  • 6

2 Answers2

0

Problem is in line loadFeed.add(feedsFile)... You are not using scanner to read.

Try this

While(s.hasNextLine()){
  loadFeed.add(s.nextLine());
}
Saurabh Nigam
  • 795
  • 6
  • 12
  • Now I get this message "The method add(Feed) in the type List is not applicable for the arguments (String)" – TotalNoob Aug 31 '20 at 08:04
  • yes s.nextLine() returns String. you can use objectMapper to convert the string to the required object. eg objectMapper.readValue(s.nextLine()); – Saurabh Nigam Aug 31 '20 at 09:11
0

Why are you trying to load from a file feed objects if the object returned by reading a file is String? The list should contain string instead of feed objects. You probably need to convert contents of your file into real object take a look to how to convert a String to Object in JAVA

Try this or something similar:

import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.util.stream.Collectors;

@Override
public List < Feed > loadSubscribedFeeds(File feedsFile) {

  List < String > list = Files.lines(Paths.get(feedsFile.getAbsolutePath()), StandardCharsets.ISO_8859_1).collect(Collectors.toList());

  List < Object > objs = new ArrayList < >();

  try {
    for (String s: list)
    objs.add(Class.forName(s).newInstance());
    //IMPORTANT! s should contain not only feed for example but com.mypackage.feed
  } catch(Exception ex) {
    System.out.println(ex.getMessage());
  }

  List < Feed > listFeed = new ArrayList < >();

  for (Object l: objs) {
    if (l instanceof Feed)
        listFeed.add((Feed) l);
  }
  return listFeed;
}

If you only need the string representation of the contents of the file instead of real objects, consider changing the return type to List<String> and return list and you're already done. And if you want to keep using your code to read the strings from a file (instead of using lambdas as I did) use nextLine (and hasNextLine()) like someone as already suggested and change List<Feed> to List<String>.

The complete code using what you already wrote is the following:

public List<Feed> loadSubscribedFeeds(File feedsFile) throws IOException {

    List<String> list = new ArrayList<>();

    try (Scanner s = new Scanner(new FileReader(feedsFile))) {
        while (s.hasNextLine()) {
            list.add(s.nextLine());
        }
    }
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    List<Object> objs = new ArrayList<>();

    try {
        for (String s : list)
            objs.add(Class.forName(s).newInstance());
        //IMPORTANT! s should contain not only feed for example but com.mypackage.feed
    }catch(Exception ex){
        System.out.println(ex.getMessage());
    }
     
    List<Feed> listFeed = new ArrayList<>();

    for (Object l : objs){
        if (l instanceof Feed)
            listFeed.add((Feed)l);
    }

    return listFeed;
}

where the file contain something just like:

mypackage.Feed
mypackage.Subfeed
//and so on...

With Subfeed a subclass of feed.

Virgula
  • 318
  • 4
  • 12
  • The problem is that I have to keep things as they are because it's an exam. I have to do it like I explained my problem in the question. – TotalNoob Aug 31 '20 at 09:13
  • @TotalNoob Updated but honestly I think you need only the string representation of elements if it's an exam, not the Feed element itself. – Virgula Aug 31 '20 at 10:02
  • It cannot convert from element type Feed to String and if I change "String s" to "Feed s" it says "The method forName(String) in the type Class is not applicable for the arguments (Feed)" – TotalNoob Aug 31 '20 at 10:17
  • @TotalNoob Does your exercise asks for string representation of the file or strings needs to be converted to Objects? If it asks for the second one you can use the code I wrote otherwise just change the return type of the method to List, after the first try catch do a “return list;”and ignore the code which converts string to object( to be precise delete from the objs declaration to the return listFeed). – Virgula Aug 31 '20 at 10:50
  • he commented this in JavaDoc: Loads the previously subscribed/added feeds data from feedsFile and returns it as a List of Feed objects. – TotalNoob Aug 31 '20 at 11:07
  • @TotalMoob well, the code above works fine, I tried it.make sure to check how classes in the file are saved. The format needs to be exactly the same of what I described. Can you post what is the content-format of feed file? – Virgula Aug 31 '20 at 11:18
  • The lecturer created a JUnit Test and it says "No feeds were read from test save-file 'feader.test.feeds'!". I don't think that the format is the problem here .. – TotalNoob Aug 31 '20 at 12:13
  • @TotalNoob by what you wrote I can understand that the class is not Feed as you wrote in your example by it’s feeds not Feed. Anyway your problem and how you described it is too confused. You need to better understand what you have to do and then update the question with correct infos. – Virgula Aug 31 '20 at 12:22
  • I posted the Feed Class above – TotalNoob Aug 31 '20 at 12:31
  • @TotalNoob Ok the difference is that in your class you have 2 constructors and not a constructor without arguments just like the default constructor. So when you create an object with Class.forName() you need to initialize the objects with one of 2 constructor available in Feed. Check out: https://stackoverflow.com/questions/5658182/initializing-a-class-with-class-forname-and-which-have-a-constructor-which-tak this explain exactly how to do it. – Virgula Aug 31 '20 at 13:19