<commit_before>package org.aikodi.chameleon.workspace;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.aikodi.chameleon.core.document.Document;
import org.aikodi.chameleon.core.element.Element;
import org.aikodi.chameleon.util.Handler;

import be.kuleuven.cs.distrinet.rejuse.action.Action;
import be.kuleuven.cs.distrinet.rejuse.association.AssociationListener;
import be.kuleuven.cs.distrinet.rejuse.association.OrderedMultiAssociation;
import be.kuleuven.cs.distrinet.rejuse.association.SingleAssociation;

/**
 * A class that represents the concept of a project. A project
 * keeps a collection document scanners that populate the project.
 * 
 * FIXME: A project should not need a root directory or know about files. 
 * That functionality should be moved to a plugin. 
 * If a project is loaded from a database, the functionality makes no sense. 
 * For now, just provide a null reference.
 * 
 * @author <NAME>
 */
public class Project {

   private OrderedMultiAssociation<Project, View> _views = new OrderedMultiAssociation<Project, View>(this);   
   {
      _views.enableCache();
   }

   private SingleAssociation<Project, Workspace> _workspaceLink = new SingleAssociation<Project, Workspace>(this);

   private File _root;

   /**
    * Create a new Chameleon project with the given name, root directory, and view.
    */
   /*@
   @ public behavior
   @
   @ pre name != null;
   @ pre root != null;
   @ pre view != null;
   @
   @ post name() == name;
   @ post root() == root;
   @ post views().contains(view);
   @*/
   public Project(String name, File root, View view) {
      this(name, root);
      addView(view);
   }

   /**
    * Create a new Chameleon project with the given name, and root directory.
    */
   /*@
   @ public behavior
   @
   @ pre name != null;
   @ pre root != null;
   @
   @ post name() == name;
   @ post root() == root;
   @*/
   public Project(String name, File root) {
      setName(name);
      setRoot(root);
      _views.addListener(new AssociationListener<View>() {

         @Override
         public void notifyElementAdded(View element) {
            notifyViewAdded(element);
         }

         @Override
         public void notifyElementRemoved(View element) {
            notifyViewRemoved(element);
         }
      });

   }

   /**
    * Notify the project listeners that a view was added.
    * 
    * @param view The view that was added.
    */
   protected void notifyViewAdded(View view) {
      for(ProjectListener listener: _listeners) {
         listener.viewAdded(view);
      }
   }

   /**
    * Notify the project listeners that a view was removed.
    * 
    * @param view The view that was removed.
    */
   protected void notifyViewRemoved(View view) {
      for(ProjectListener listener: _listeners) {
         listener.viewRemoved(view);
      }
   }

   /**
    * Add the given project listener.
    * 
    * @param listener The listener to be added.
    */
   public void addProjectListener(ProjectListener listener) {
      if(listener == null) {
         throw new IllegalArgumentException();
      }
      _listeners.add(listener);
   }

   /**
    * Remove the given project listener.
    * 
    * @param listener The listener to be removed.
    */
   public void removeProjectListener(ProjectListener listener) {
      _listeners.remove(listener);
   }


   private List<ProjectListener> _listeners = new ArrayList<ProjectListener>();

   /**
    * Add the given view to the project. The project listeners
    * will be notified afterwards.
    * 
    * @param view The view to be added.
    */
   /*@
   @ public behavior
   @
   @ pre view != null;
   @ pre ! views().contains(view);
   @
   @ post views().contains(view);
   @ post views().size() == \old(views().size()) + 1;
   @*/
   public void addView(View view) {
      if(view != null) {
         _views.add(view.projectLink());
      } else {
         throw new IllegalArgumentException();
      }
   }

   /**
    * Return the views of this project.
    */
   /*@
   @ public behavior
   @
   @ post \result != null;
   @*/
   public List<View> views() {
      return _views.getOtherEnds();
   }

   /**
    * Return the root directory of the project. The root directory is
    * used to transform relative paths used in project files to
    * absolute paths. 
    */
   public File root() {
      return _root;
   }

   /**
    * Set the root directory of this project.
    * 
    * @param rootDirectory The new root directory of the project.
    */
   /*@
   @ public behavior
   @
   @ pre rootDirectory != null;
   @
   @ post root() == rootDirectory;
   @*/
   protected void setRoot(File rootDirectory) {
      if(rootDirectory != null && rootDirectory.isFile()) {
         throw new IllegalArgumentException("The root directory of a project should not be a normal file");
      }
      _root = rootDirectory;<commit_msg>Added a method for finding the view of a language<commit_after>package org.aikodi.chameleon.workspace;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.aikodi.chameleon.core.document.Document;
import org.aikodi.chameleon.core.element.Element;
import org.aikodi.chameleon.core.language.Language;
import org.aikodi.chameleon.util.Handler;

import be.kuleuven.cs.distrinet.rejuse.action.Action;
import be.kuleuven.cs.distrinet.rejuse.association.AssociationListener;
import be.kuleuven.cs.distrinet.rejuse.association.OrderedMultiAssociation;
import be.kuleuven.cs.distrinet.rejuse.association.SingleAssociation;

/**
 * A class that represents the concept of a project. A project
 * keeps a collection document scanners that populate the project.
 * 
 * FIXME: A project should not need a root directory or know about files. 
 * That functionality should be moved to a plugin. 
 * If a project is loaded from a database, the functionality makes no sense. 
 * For now, just provide a null reference.
 * 
 * @author <NAME>
 */
public class Project {

   private OrderedMultiAssociation<Project, View> _views = new OrderedMultiAssociation<Project, View>(this);   
   {
      _views.enableCache();
   }

   private SingleAssociation<Project, Workspace> _workspaceLink = new SingleAssociation<Project, Workspace>(this);

   private File _root;

   /**
    * Create a new Chameleon project with the given name, root directory, and view.
    */
   /*@
   @ public behavior
   @
   @ pre name != null;
   @ pre root != null;
   @ pre view != null;
   @
   @ post name() == name;
   @ post root() == root;
   @ post views().contains(view);
   @*/
   public Project(String name, File root, View view) {
      this(name, root);
      addView(view);
   }

   /**
    * Create a new Chameleon project with the given name, and root directory.
    */
   /*@
   @ public behavior
   @
   @ pre name != null;
   @ pre root != null;
   @
   @ post name() == name;
   @ post root() == root;
   @*/
   public Project(String name, File root) {
      setName(name);
      setRoot(root);
      _views.addListener(new AssociationListener<View>() {

         @Override
         public void notifyElementAdded(View element) {
            notifyViewAdded(element);
         }

         @Override
         public void notifyElementRemoved(View element) {
            notifyViewRemoved(element);
         }
      });

   }

   /**
    * Notify the project listeners that a view was added.
    * 
    * @param view The view that was added.
    */
   protected void notifyViewAdded(View view) {
      for(ProjectListener listener: _listeners) {
         listener.viewAdded(view);
      }
   }

   /**
    * Notify the project listeners that a view was removed.
    * 
    * @param view The view that was removed.
    */
   protected void notifyViewRemoved(View view) {
      for(ProjectListener listener: _listeners) {
         listener.viewRemoved(view);
      }
   }

   /**
    * Add the given project listener.
    * 
    * @param listener The listener to be added.
    */
   public void addProjectListener(ProjectListener listener) {
      if(listener == null) {
         throw new IllegalArgumentException();
      }
      _listeners.add(listener);
   }

   /**
    * Remove the given project listener.
    * 
    * @param listener The listener to be removed.
    */
   public void removeProjectListener(ProjectListener listener) {
      _listeners.remove(listener);
   }


   private List<ProjectListener> _listeners = new ArrayList<ProjectListener>();

   /**
    * Add the given view to the project. The project listeners
    * will be notified afterwards.
    * 
    * @param view The view to be added.
    */
   /*@
   @ public behavior
   @
   @ pre view != null;
   @ pre ! views().contains(view);
   @
   @ post views().contains(view);
   @ post views().size() == \old(views().size()) + 1;
   @*/
   public void addView(View view) {
      if(view != null) {
         _views.add(view.projectLink());
      } else {
         throw new IllegalArgumentException();
      }
   }

   /**
    * Return the views of this project.
    */
   /*@
   @ public behavior
   @
   @ post \result != null;
   @*/
   public List<View> views() {
      return _views.getOtherEnds();
   }
   
   /**
    * Return a view with the given language.
    * 
    * @param language The language of the returned view.
    * @return a view in this project that has the given language. 
    */
   public View view(Language language) {
     if(language == null) {
       throw new IllegalArgumentException("The language cannot be null.");
     }
     for(View view: views()) {
       if(view.language().equals(language)) {
         return view;
       }
     }
     throw new IllegalArgumentException("There is no view for "+language.name()+" "+language.version());
   }

   /**
    * Return the root directory of the project. The root directory is
    * used to transform relative paths used in project files to
    * absolute paths. 
    */
   public File root() {
      return _root;
   }

   /**
    * Set the root directory of this project.
    * 
    * @param rootDirectory The new root directory of the project.
    */
   /*@
   @ public behavior
   @
   @ pre rootDirectory != null;
   @
   @ post root() == rootDirectory;
   @*/
   protected void setRoot(File rootDirectory) {
      if(rootDirectory != null && rootDirectory.isFile()) {
         throw new IllegalArgumentException("The root directory of a project should not be a normal file");
      }
      _root = rootDirectory;
{'fraction_non_alphanumeric': 0.10791229742612012, 'fraction_numerical': 0.00019065776930409913, 'mean_word_length': 2.5418636056718436, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7550564', 'n_tokens_mistral': 3083, 'n_tokens_neox': 3001, 'n_words': 911}