// Path: src/main/java/org/latna/msw/MetricElement.java
// public abstract class MetricElement {
//     private final List<MetricElement> friends;
// 
//     public MetricElement() {
//         friends = Collections.synchronizedList(new ArrayList());
//     }
//     
//     /**
//      * Calculate metric between current object and another.
//      * @param gme any element for whose metric can be calculated. Any element from domain set. 
//      * @return distance value
//      */
//     public abstract double calcDistance(MetricElement gme);
// 
//     public synchronized List<MetricElement> getAllFriends() {
//         return friends;
//     }
// 
//     public List<MetricElement> getAllFriendsOfAllFriends() {
//         HashSet <MetricElement> hs=new HashSet();
//         hs.add(this);
//         for(int i=0;i<friends.size();i++){
//             hs.add(friends.get(i));
//             for(int j=0;j<friends.get(i).getAllFriends().size();j++)
//                 hs.add(friends.get(i).getAllFriends().get(j));
//         }
//         return new ArrayList(hs);
//     }
// 
//     public MetricElement getClosestElemet(MetricElement q) {
//         double min=this.calcDistance(q);
//         int nummin=-1;
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
//             if(temp<min){
//                 nummin=i;
//                 min=temp;
//             }
// 
//         }
//         if(nummin==-1)
//             return this;
//         else
//             return friends.get(nummin);
//     }
// 
//     public SearchResult getClosestElemetSearchResult(MetricElement q) {
//         SearchResult s;
//         TreeSet <EvaluatedElement> set = new TreeSet();
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
// 
//             set.add(new EvaluatedElement(temp, friends.get(i)));
// 
//         }
//         return new SearchResult(set, null);
//     }
// 
//     public synchronized void addFriend(MetricElement e) {
//         if(!friends.contains(e))
//             friends.add(e);
//     }
// 
//     public synchronized void removeFriend(MetricElement e) {
//         if(friends.contains(e))
//             friends.remove(e);
//     }
// 
//     public synchronized void removeAllFriends() {
//         friends.clear();
//     }
// 
// }
// 
// Path: src/main/java/org/latna/msw/MetricElementFactory.java
// public interface MetricElementFactory {
//     /**
//      * 
//      * @return List of Metric elements
//      */
//     public List <MetricElement> getElements();
//     /**
//      * Distinct implementation can have many configuration which may be incompatible 
//      * among themselves, therefore we use String to pass configuration to the factory
//      * @param param configuration string for the factory
//      */
//     public void setParameterString(String param);
// }
// 
// Path: src/main/java/org/latna/msw/documents/Document.java
// public class Document  extends MetricElement {
//     private Map <String, Double> termVector;
//     String id;
// 
//     public Document(String id) {
//         super();
//         termVector = new HashMap();
//         this.id = id;
//     }
// 
//     public void addTerm(String termId, double value) {
//          termVector.put(termId, value);
//     }
// 
//     @Override
//     public double calcDistance(MetricElement gme) {
//         double res = 0;
//         if (!(gme instanceof Document)) {
//             throw new Error("You are trying calculate distance for the non-Document type object");
//         }
//         Document otherDoc = (Document) gme;
//         Document doc1;
//         Document doc2;
// 
//         if (otherDoc.termVector.size() < this.termVector.size()) {
//             doc1 = otherDoc;    
//             doc2 = this;
//         } else {
//             doc1 = this;
//             doc2 = otherDoc;
//         }
// 
//         for ( Entry <String, Double>  i :  doc1.termVector.entrySet()) {
//             if (doc2.termVector.containsKey(i.getKey()) ) {
//                 res = res + i.getValue()*doc2.termVector.get(i.getKey());
//             }
//         }
// 
//         res  = res / (  doc1.getVectorLenght() * doc2.getVectorLenght()  );
//         res = java.lang.Math.acos(res);
//         return res;
//     }
// 
//     private double getVectorLenght() {
//         double res = 0;
// 
//         for (Double d: termVector.values())
//             res = res + d*d;
// 
//         return Math.sqrt(res);
//     }
// 
//     public boolean equals(Object o) {
//         Document otherDocument = (Document) o ;
//         return otherDocument.termVector.equals(this.termVector);
//     }
// 
// }


import org.latna.msw.MetricElement;
import org.latna.msw.MetricElementFactory;
import org.latna.msw.documents.Document;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
package org.latna.msw.wikisparse;


public class WikiSparseFactory {
    public String inputFilePath="G:\\WikiData\\wikipedia.txt";
    private int maxDoc; 
    private Scanner globalScanner = null;

    public WikiSparseFactory(String inputFilePath) {
        if (!inputFilePath.isEmpty())
            this.inputFilePath = inputFilePath;
        
        try {
            globalScanner = new Scanner(new File(this.inputFilePath));
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        }
    }
    
// Path: src/main/java/org/latna/msw/MetricElement.java
// public abstract class MetricElement {
//     private final List<MetricElement> friends;
// 
//     public MetricElement() {
//         friends = Collections.synchronizedList(new ArrayList());
//     }
//     
//     /**
//      * Calculate metric between current object and another.
//      * @param gme any element for whose metric can be calculated. Any element from domain set. 
//      * @return distance value
//      */
//     public abstract double calcDistance(MetricElement gme);
// 
//     public synchronized List<MetricElement> getAllFriends() {
//         return friends;
//     }
// 
//     public List<MetricElement> getAllFriendsOfAllFriends() {
//         HashSet <MetricElement> hs=new HashSet();
//         hs.add(this);
//         for(int i=0;i<friends.size();i++){
//             hs.add(friends.get(i));
//             for(int j=0;j<friends.get(i).getAllFriends().size();j++)
//                 hs.add(friends.get(i).getAllFriends().get(j));
//         }
//         return new ArrayList(hs);
//     }
// 
//     public MetricElement getClosestElemet(MetricElement q) {
//         double min=this.calcDistance(q);
//         int nummin=-1;
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
//             if(temp<min){
//                 nummin=i;
//                 min=temp;
//             }
// 
//         }
//         if(nummin==-1)
//             return this;
//         else
//             return friends.get(nummin);
//     }
// 
//     public SearchResult getClosestElemetSearchResult(MetricElement q) {
//         SearchResult s;
//         TreeSet <EvaluatedElement> set = new TreeSet();
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
// 
//             set.add(new EvaluatedElement(temp, friends.get(i)));
// 
//         }
//         return new SearchResult(set, null);
//     }
// 
//     public synchronized void addFriend(MetricElement e) {
//         if(!friends.contains(e))
//             friends.add(e);
//     }
// 
//     public synchronized void removeFriend(MetricElement e) {
//         if(friends.contains(e))
//             friends.remove(e);
//     }
// 
//     public synchronized void removeAllFriends() {
//         friends.clear();
//     }
// 
// }
// 
// Path: src/main/java/org/latna/msw/MetricElementFactory.java
// public interface MetricElementFactory {
//     /**
//      * 
//      * @return List of Metric elements
//      */
//     public List <MetricElement> getElements();
//     /**
//      * Distinct implementation can have many configuration which may be incompatible 
//      * among themselves, therefore we use String to pass configuration to the factory
//      * @param param configuration string for the factory
//      */
//     public void setParameterString(String param);
// }
// 
// Path: src/main/java/org/latna/msw/documents/Document.java
// public class Document  extends MetricElement {
//     private Map <String, Double> termVector;
//     String id;
// 
//     public Document(String id) {
//         super();
//         termVector = new HashMap();
//         this.id = id;
//     }
// 
//     public void addTerm(String termId, double value) {
//          termVector.put(termId, value);
//     }
// 
//     @Override
//     public double calcDistance(MetricElement gme) {
//         double res = 0;
//         if (!(gme instanceof Document)) {
//             throw new Error("You are trying calculate distance for the non-Document type object");
//         }
//         Document otherDoc = (Document) gme;
//         Document doc1;
//         Document doc2;
// 
//         if (otherDoc.termVector.size() < this.termVector.size()) {
//             doc1 = otherDoc;    
//             doc2 = this;
//         } else {
//             doc1 = this;
//             doc2 = otherDoc;
//         }
// 
//         for ( Entry <String, Double>  i :  doc1.termVector.entrySet()) {
//             if (doc2.termVector.containsKey(i.getKey()) ) {
//                 res = res + i.getValue()*doc2.termVector.get(i.getKey());
//             }
//         }
// 
//         res  = res / (  doc1.getVectorLenght() * doc2.getVectorLenght()  );
//         res = java.lang.Math.acos(res);
//         return res;
//     }
// 
//     private double getVectorLenght() {
//         double res = 0;
// 
//         for (Double d: termVector.values())
//             res = res + d*d;
// 
//         return Math.sqrt(res);
//     }
// 
//     public boolean equals(Object o) {
//         Document otherDocument = (Document) o ;
//         return otherDocument.termVector.equals(this.termVector);
//     }
// 
// }


// Path: src/main/java/org/latna/msw/wikisparse/WikiSparseFactory.java
import org.latna.msw.MetricElement;
import org.latna.msw.MetricElementFactory;
import org.latna.msw.documents.Document;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

package org.latna.msw.wikisparse;


public class WikiSparseFactory {
    public String inputFilePath="G:\\WikiData\\wikipedia.txt";
    private int maxDoc; 
    private Scanner globalScanner = null;

    public WikiSparseFactory(String inputFilePath) {
        if (!inputFilePath.isEmpty())
            this.inputFilePath = inputFilePath;
        
        try {
            globalScanner = new Scanner(new File(this.inputFilePath));
        } catch (FileNotFoundException ex) {
            System.out.println(ex);
        }
    }
    
    public MetricElement getElement() {