Catalogue.cs

00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004 using System.Data;
00005 using Shared;
00006 using Server.Data;
00007 using System.Text.RegularExpressions;
00008 
00009 namespace Server
00010 {
00015     public class Catalogue
00016     {
00017         #region Constructor and class variables
00018         
00019         private IPersistentData database;
00020         private DataContainer data;
00021         private int UniqueTagCount = -1;
00022 
00027         public Catalogue(IPersistentData database)
00028         {
00029             this.database = database;
00030             data = database.LoadData();
00031         }
00032 
00036         public void SaveData()
00037         {
00038             database.SaveData(data);
00039         }
00040 
00041         #endregion
00042 
00043         #region Project methods
00044 
00050         public Project GetProject(int id)
00051         {
00052             if (data.ProjectTable.ContainsKey(id))
00053             {
00054                 return data.ProjectTable[id];
00055             }
00056             return null;
00057         }
00063         public ProjectInfo GetProjectInfo(int id)
00064         {
00065             if (data.ProjectTable.ContainsKey(id))
00066             {
00067                 return data.ProjectTable[id].Info;
00068             }
00069             return new ProjectInfo();
00070         }
00076         public Messages DeleteProject(int id)
00077         {
00078             if (!data.ProjectTable.ContainsKey(id)) return Messages.Fail;
00079 
00080             DataRow[] rows = data.Tags.Select("ID = '" + id.ToString() + "'");
00081             
00082             if (rows.Length > 0)
00083             {
00084                 foreach (DataRow dr in rows)
00085                 {
00086                     data.Tags.Rows.Remove(dr);    
00087                 }
00088                                 
00089                 data.Tags.AcceptChanges();
00090                 
00091             }
00092 
00093             List<Reference> references = new List<Reference>();
00094             references.AddRange(data.ProjectTable[id].References);
00095 
00096             foreach (Reference r in references)
00097             {
00098                 DeleteReference(r.Project.ID, r.Literature.ID);
00099             }
00100 
00101 
00102             data.ProjectTable.Remove(id);
00103             database.SaveData(data);
00104 
00105             return Messages.OK;
00106         }
00115         public Messages CreateProject(ProjectInfo pi, string creator, out int id)
00116         {
00117             id = -1;
00118             Person person = GetUser(creator);
00119             if (person == null)
00120                 return Messages.Fail;
00121 
00122             id = UniquelyIdentifiable.NextID;
00123             Project p = new Project(id, pi.startDate, pi.endDate, pi.subject, pi.title, pi.department, pi.synopsis, pi.submitted);
00124             p.AddPerson(person, RoleType.Creator);
00125             data.ProjectTable.Add(p.ID, p);
00126 
00128             database.SaveData(data);
00129 
00130             return Messages.OK;
00131         }
00137         public Messages UpdateProject(ProjectInfo info)
00138         {
00139             if (!data.ProjectTable.ContainsKey(info.id))
00140                 return Messages.Fail;
00141 
00142             Project p = data.ProjectTable[info.id];
00143             p.IsSubmitted = info.submitted;
00144             p.StartDate = info.startDate;
00145             p.Subject = info.subject;
00146             p.Synopsis = info.synopsis;
00147             p.Title = info.title;
00148             p.EndDate = info.endDate;
00149             p.Department = info.department;
00150             return Messages.OK;
00151         }
00156         public ProjectInfo[] ListProjects()
00157         {
00158             ProjectInfo[] infos = new ProjectInfo[data.ProjectTable.Count];
00159             int i = 0;
00160             foreach (Project project in data.ProjectTable.Values)
00161             {
00162                 infos[i++] = project.Info;
00163             }
00164 
00165             return infos;
00166         }
00172         public ProjectInfo[] GetUsersProjects(string username)
00173         {
00174             List<ProjectInfo> result = new List<ProjectInfo>();
00175 
00176             foreach (KeyValuePair<int, Project> p in data.ProjectTable)
00177             {
00178                 foreach (Role r in p.Value.Roles)
00179                 {
00180                     if (r.Person.UserName == username) result.Add(new ProjectInfo(p.Value.ID,
00181                         p.Value.StartDate, p.Value.EndDate, p.Value.Subject, p.Value.Title, p.Value.Department,
00182                         p.Value.Synopsis, p.Value.IsSubmitted));
00183                 }
00184             }
00185 
00186             return result.ToArray();
00187         }
00188         
00189         #endregion
00190 
00191         #region Literature methods
00192 
00200         public Messages CreateLiterature(LiteratureInfo info, out int id)
00201         {
00202             id = -1;
00203             if (!data.PersonTable.ContainsKey(info.creator))
00204                 return Messages.Fail;
00205             id = UniquelyIdentifiable.NextID;
00206             Literature l = new Literature(id, data.PersonTable[info.creator], info.title, info.author, info.summary, info.source, info.isbn, info.date, info.type);
00207             data.LiteratureTable.Add(l.ID, l);
00208 
00210             database.SaveData(data);
00211 
00212             return Messages.OK;
00213         }
00218         public LiteratureInfo[] ListLiterature()
00219         {
00220             LiteratureInfo[] infos = new LiteratureInfo[data.LiteratureTable.Count];
00221             int i = 0;
00222             foreach (Literature literature in data.LiteratureTable.Values)
00223             {
00224                 infos[i++] = literature.Info;
00225             }
00226 
00227             return infos;
00228         }
00234         public Messages DeleteLiterature(int id)
00235         {
00236             if (!data.LiteratureTable.ContainsKey(id)) return Messages.Fail;
00237 
00238             DataRow[] rows = data.Tags.Select("ID = '" + id.ToString() + "'");
00239 
00240             if (rows.Length > 0)
00241             {
00242                 foreach (DataRow dr in rows)
00243                 {
00244                     data.Tags.Rows.Remove(dr);
00245                 }
00246 
00247                 data.Tags.AcceptChanges();
00248 
00249             }
00250 
00251             data.LiteratureTable.Remove(id);
00252             database.SaveData(data);
00253 
00254             return Messages.OK;
00255         }
00261         public LiteratureInfo GetLiteratureInfo(int id)
00262         {
00263             if (data.LiteratureTable.ContainsKey(id))
00264             {
00265                 return data.LiteratureTable[id].Info;
00266             }
00267             return new LiteratureInfo();
00268         }
00274         public Messages UpdateLiterature(LiteratureInfo info)
00275         {
00276             if (!data.LiteratureTable.ContainsKey(info.id))
00277                 return Messages.Fail;
00278 
00279             Literature l = data.LiteratureTable[info.id];
00280             l.Author = info.author;
00281             l.ISBN = info.isbn;
00282             l.Source = info.source;
00283             l.Summary = info.summary;
00284             l.Title = info.title;
00285             l.Type = info.type;
00286             return Messages.OK;
00287         }
00288         
00289         #endregion
00290 
00291         #region Comment methods
00292 
00299         public Messages CreateComment(CommentInfo ci, out int id)
00300         {
00301             id = -1;
00302             if (ci.type == CommentType.Literature)
00303             {
00304                 id = ci.id = UniquelyIdentifiable.NextID;
00305                 Comment c = new Comment(ci.id, data.PersonTable[ci.poster], ci.title, ci.text, ci.type, ci.date);
00306                 data.LiteratureTable[ci.parent].Comments.Add(c);
00307                 data.CommentTable.Add(ci.id, c);
00308             }
00309 
00310             if (ci.type == CommentType.Reference)
00311             {
00312                 Reference r = GetReference(ci.project, ci.parent);
00313 
00314                 if (r != null)
00315                 {
00316                     id = ci.id = UniquelyIdentifiable.NextID;
00317                     Comment c = new Comment(ci.id, data.PersonTable[ci.poster], ci.title, ci.text, ci.type, ci.date);
00318                     r.Comments.Add(c);
00319                     data.CommentTable.Add(ci.id, c);
00320 
00321                     return Messages.OK;
00322                 }
00323 
00324                 return Messages.Fail;
00325 
00326             }
00327 
00328             if (ci.type == CommentType.Comment)
00329             {
00330                 id = ci.id = UniquelyIdentifiable.NextID;
00331                 Comment c = new Comment(ci.id, data.PersonTable[ci.poster], ci.title, ci.text, ci.type, ci.date);
00332                 data.CommentTable[ci.parent].Comments.Add(c);
00333                 data.CommentTable.Add(ci.id, c);
00334             }
00335 
00336             return Messages.OK;
00337 
00338         }
00344         public CommentInfo[] GetComments(int literatureID)
00345         {
00346             List<CommentInfo> result = new List<CommentInfo>();
00347             Literature temp;
00348             
00349             try
00350             {
00351                 data.LiteratureTable.TryGetValue(literatureID, out temp);
00352             }
00353             catch (KeyNotFoundException) { return null; }
00354 
00355             GetAllComments(temp.Comments, result, temp.ID, -1);
00356 
00357             return result.ToArray();
00358         }
00365         public CommentInfo[] GetComments(int literatureID, int projectID)
00366         {
00367             List<CommentInfo> result = new List<CommentInfo>();
00368 
00369             Reference r = GetReference(projectID, literatureID);
00370 
00371             GetAllComments(r.Comments, result, literatureID, projectID);
00372                         
00373             return result.ToArray();
00374         }
00375         private void GetAllComments(List<Comment> root, List<CommentInfo> output, int parent, int project)
00376         {
00377             foreach (Comment c in root)
00378             {
00379                 output.Add(new CommentInfo(c.ID, parent, project, c.Poster.UserName, c.Title, c.Text, c.Date, c.CommentType));
00380                 GetAllComments(c.Comments, output, c.ID, project);
00381             }
00382 
00383         }
00384 
00385         #endregion
00386 
00387         #region Review methods
00388 
00395         public ReviewInfo GetReviewInfo(int project, int literature)
00396         {
00397             Reference r = GetReference(project, literature);
00398             if (r == null)
00399                 return new ReviewInfo();
00400 
00401             if (r is Review)
00402             {
00403                 return ((Review)r).Info;
00404             }
00405 
00406             return new ReviewInfo();
00407         }
00413         public ReviewInfo[] ListReviews(int project)
00414         {
00415             List<ReviewInfo> infos = new List<ReviewInfo>();
00416 
00417             if (!data.ProjectTable.ContainsKey(project) && !data.LiteratureTable.ContainsKey(project))
00418                 return null;
00419 
00420             List<Reference> refs = data.ProjectTable.ContainsKey(project) ? data.ProjectTable[project].References : data.LiteratureTable[project].References;
00421 
00422             foreach (Reference r in refs)
00423             {
00424                 if (r is Review)
00425                 {
00426                     infos.Add(((Review)r).Info);
00427                 }
00428             }
00429             return infos.ToArray();
00430         }
00436         public Messages CreateReview(ReviewInfo ri)
00437         {
00438             Reference r = GetReference(ri.project, ri.literature);
00439             if (r != null && (r is Review))
00440                 return Messages.Fail;
00441 
00442             if (!data.PersonTable.ContainsKey(ri.person))
00443                 return Messages.Fail;
00444 
00445             List<Comment> comments = null;
00446             if (r is Reference)
00447             {
00448                 comments = r.Comments;
00449                 DeleteReference(ri.project, ri.literature);
00450             }
00451 
00452             Review rv = new Review(data.ProjectTable[ri.project], data.PersonTable[ri.person], data.LiteratureTable[ri.literature], ri.date, ri.used, ri.status, ri.title, ri.text, ri.rating);
00453             if (comments != null)
00454                 rv.Comments.AddRange(comments);
00455 
00456 
00457             data.ProjectTable[ri.project].References.Add(rv);
00458             data.LiteratureTable[ri.literature].References.Add(rv);
00459             return Messages.OK;
00460         }
00466         public Messages UpdateReview(ReviewInfo ri)
00467         {
00468             Reference r = GetReference(ri.project, ri.literature);
00469             if (r == null || !(r is Review))
00470                 return Messages.Fail;
00471 
00472             Review rv = (Review)r;
00473 
00474             rv.Date = ri.date;
00475             rv.Status = ri.status;
00476             rv.Used = ri.used;
00477             rv.Title = ri.title;
00478             rv.Text = ri.text;
00479             rv.Rating = ri.rating;
00480             return Messages.OK;
00481         }
00482 
00483         #endregion
00484 
00485         #region Reference methods
00486 
00492         public Messages CreateReference(ReferenceInfo ri)
00493         {
00494             if (!data.ProjectTable.ContainsKey(ri.project) || !data.LiteratureTable.ContainsKey(ri.literature))
00495                 return Messages.Fail;
00496 
00497             Reference r = GetReference(ri.project, ri.literature);
00498             if (r != null)
00499                 return Messages.Fail;
00500 
00501             Reference re = new Reference(data.ProjectTable[ri.project], data.LiteratureTable[ri.literature], ri.date, ri.used, ri.status);
00502             data.ProjectTable[ri.project].References.Add(re);
00503             data.LiteratureTable[ri.literature].References.Add(re);
00504             return Messages.OK;
00505         }
00511         public Messages UpdateReference(ReferenceInfo ri)
00512         {
00513             Reference r = GetReference(ri.project, ri.literature);
00514             if (r == null)
00515                 return Messages.Fail;
00516 
00517             r.Date = ri.date;
00518             r.Status = ri.status;
00519             r.Used = ri.used;
00520             return Messages.OK;
00521         }
00528         private Reference GetReference(int project, int literature)
00529         {
00530             if (!data.ProjectTable.ContainsKey(project))
00531                 return null;
00532 
00533             foreach (Reference r in data.ProjectTable[project].References)
00534             {
00535                 if (r.Literature.ID == literature)
00536                     return r;
00537             }
00538             return null;
00539         }
00546         public Messages DeleteReference(int project, int literature)
00547         {
00548             Reference reference = GetReference(project, literature);
00549             if (reference == null)
00550                 return Messages.Fail;
00551 
00552             data.ProjectTable[project].References.Remove(reference);
00553             data.LiteratureTable[literature].References.Remove(reference);
00554             return Messages.OK;
00555         }
00562         public ReferenceInfo GetReferenceInfo(int project, int literature)
00563         {
00564             Reference r = GetReference(project, literature);
00565             if (r == null)
00566                 return new ReferenceInfo();
00567 
00568             if (r is Reference)
00569             {
00570                 return ((Reference)r).Info;
00571             }
00572 
00573             return new ReferenceInfo();
00574         }
00580         public ReferenceInfo[] ListReferences(int project)
00581         {
00582             List<ReferenceInfo> infos = new List<ReferenceInfo>();
00583 
00584             if (!data.ProjectTable.ContainsKey(project) && !data.LiteratureTable.ContainsKey(project))
00585                 return null;
00586 
00587             List<Reference> refs = data.ProjectTable.ContainsKey(project) ? data.ProjectTable[project].References : data.LiteratureTable[project].References;
00588 
00589             foreach (Reference r in refs)
00590             {
00591                 if (r is Reference && !(r is Review) && !(r is Suggestion))
00592                 {
00593                     infos.Add(r.Info);
00594                 }
00595             }
00596             return infos.ToArray();
00597         }
00598 
00599         #endregion
00600 
00601         #region Suggestion methods
00602 
00608         public Messages CreateSuggestion(SuggestionInfo si)
00609         {
00610             Reference r = GetReference(si.project, si.literature);
00611             if (r != null && !(r is Reference))
00612                 return Messages.Fail;
00613 
00614             if (!data.PersonTable.ContainsKey(si.person))
00615                 return Messages.Fail;
00616 
00617             List<Comment> comments = null;
00618             if (r is Reference)
00619             {
00620                 comments = r.Comments;
00621                 DeleteReference(si.project, si.literature);
00622             }
00623 
00624             Suggestion rv = new Suggestion(data.ProjectTable[si.project], data.PersonTable[si.person], data.LiteratureTable[si.literature], si.date, si.used, si.status, si.reason);
00625             if (comments != null)
00626                 rv.Comments.AddRange(comments);
00627             
00628             data.ProjectTable[si.project].References.Add(rv);
00629             data.LiteratureTable[si.literature].References.Add(rv);
00630             return Messages.OK;
00631         }
00637         public Messages UpdateSuggestion(SuggestionInfo si)
00638         {
00639             Reference r = GetReference(si.project, si.literature);
00640             if (r == null || !(r is Suggestion))
00641                 return Messages.Fail;
00642 
00643             Suggestion s = (Suggestion)r;
00644 
00645             s.Date = si.date;
00646             s.Status = si.status;
00647             s.Used = si.used;
00648             s.Reason = si.reason;
00649             return Messages.OK;
00650         }
00657         public SuggestionInfo GetSuggestionInfo(int project, int literature)
00658         {
00659             Reference r = GetReference(project, literature);
00660             if (r == null)
00661                 return new SuggestionInfo();
00662 
00663             if (r is Suggestion)
00664             {
00665                 return ((Suggestion)r).Info;
00666             }
00667 
00668             return new SuggestionInfo();
00669         }
00675         public SuggestionInfo[] ListSuggestions(int project)
00676         {
00677             List<SuggestionInfo> infos = new List<SuggestionInfo>();
00678 
00679             if (!data.ProjectTable.ContainsKey(project) && !data.LiteratureTable.ContainsKey(project))
00680                 return null;
00681 
00682             List<Reference> refs = data.ProjectTable.ContainsKey(project) ? data.ProjectTable[project].References : data.LiteratureTable[project].References;
00683 
00684             foreach (Reference r in refs)
00685             {
00686                 if (r is Suggestion)
00687                 {
00688                     infos.Add(((Suggestion)r).Info);
00689                 }
00690             }
00691             return infos.ToArray();
00692         }
00693 
00694         #endregion
00695 
00696         #region Search methods
00697 
00704         private float TermFrequency(string input, string query)
00705         {
00706             string[] result = input.ToLower().Split(new string[] { query.ToLower() }, StringSplitOptions.None);
00707             return result.Length - 1;
00708         }
00714         private float WordCount(string input)
00715         {
00716             string replaced = Regex.Replace(input, @"[^\w]+", " ");
00717 
00718             string[] words = replaced.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
00719             return words.Length;
00720         }
00729         private float TermFreq(string title, string text, string query)
00730         {
00731             float tf = 0, tmpTf;
00732 
00733             tmpTf = TermFrequency(title, query);
00734             if (tmpTf > 0)
00735             {
00736                 tmpTf *= 2;
00737                 tf += tmpTf;
00738             }
00739 
00740             tmpTf = TermFrequency(text, query);
00741             if (tmpTf > 0)
00742                 tf += tmpTf / WordCount(text);
00743             return tf;
00744         }
00751         public List<SearchResult> Search(string query, ResultType searchTypes)
00752         {
00753             query = query.ToLower().Trim();
00754             List<SearchResult> results = new List<SearchResult>();
00755 
00756             if (query.Length < 3)
00757                 return results;
00758 
00759             int totalDocuments = 0;
00760 
00761             if ((searchTypes & ResultType.Literature) == ResultType.Literature)
00762                 foreach (Literature lit in data.LiteratureTable.Values)
00763                 {
00764                     StringBuilder people = new StringBuilder();
00765                     foreach (Reference re in lit.References)
00766                     {
00767                         foreach (Role role in re.Project.Roles)
00768                         {
00769                             people.AppendLine(role.Person.Name + " " + role.Person.UserName);
00770                         }
00771                     }
00772 
00773                     float tf = TermFreq(String.Join(" ", new string[] { lit.Author, lit.ISBN, lit.Title, lit.Creator.UserName, lit.Creator.Name, people.ToString() }), lit.Summary, query);
00774                     
00775                     
00776                     if (tf > 0)
00777                         results.Add(new SearchResult(tf, lit.Info));
00778 
00779                     totalDocuments++;
00780                     // AddComments
00781                 }
00782 
00783             if ((searchTypes & ResultType.Person) == ResultType.Person)
00784                 foreach (Person person in data.PersonTable.Values)
00785                 {
00786                     float tf = TermFreq(String.Join(" ", new string[] { person.Name, person.UserName }), person.Department, query);
00787 
00788                     if (tf > 0)
00789                         results.Add(new SearchResult(tf, person.Info));
00790 
00791                     totalDocuments++;
00792                 }
00793 
00794             if ((searchTypes & ResultType.Project) == ResultType.Project || (searchTypes & ResultType.Review) == ResultType.Review)
00795                 foreach (Project project in data.ProjectTable.Values)
00796                 {
00797                     if ((searchTypes & ResultType.Project) == ResultType.Project)
00798                     {
00799                         StringBuilder sb = new StringBuilder();
00800                         foreach (Role r in project.Roles)
00801                         {
00802                             sb.Append(r.Person.UserName + " " + r.Person.Name + " ");
00803                             // Addcomments
00804                         }
00805 
00806 
00807                         float tf = TermFreq(String.Join(" ", new string[] { project.Title, project.Subject }), project.Department + " " + project.Synopsis + " " + sb.ToString(), query);
00808 
00809 
00810 
00811                         if (tf > 0)
00812                         {
00813                             results.Add(new SearchResult(tf, project.Info));
00814                         }
00815                         totalDocuments++;
00816                     }
00817 
00818                     if ((searchTypes & ResultType.Review) == ResultType.Review)
00819                     {
00820                         foreach (Reference r in project.References)
00821                         {
00822                             if (!(r is Review))
00823                                 continue;
00824 
00825                             Review review = (Review)r;
00826 
00827                             float tf2 = TermFreq(review.Title, review.Text, query);
00828 
00829                             if (tf2 > 0)
00830                                 results.Add(new SearchResult(tf2, review.Info));
00831 
00832                             totalDocuments++;
00833                             // Addcomments
00834                         }
00835                     }
00836 
00837 
00838                 }
00839             for (int i = 0; i < results.Count; i++)
00840             {
00841                 results[i].Relevance /= ((float)results.Count / (float)totalDocuments);
00842             }
00843 
00844 
00845             return results;
00846         }
00852         public ISearchable[] ListItems(ResultType type)
00853         {
00854             List<ISearchable> searchables = new List<ISearchable>();
00855 
00856             if ((type & ResultType.Project) == ResultType.Project)
00857             {
00858                 foreach (Project p in data.ProjectTable.Values)
00859                     searchables.Add(p.Info);
00860             }
00861 
00862             if ((type & ResultType.Literature) == ResultType.Literature)
00863             {
00864                 foreach (Literature p in data.LiteratureTable.Values)
00865                     searchables.Add(p.Info);
00866             }
00867 
00868             if ((type & ResultType.Person) == ResultType.Person)
00869             {
00870                 foreach (Person p in data.PersonTable.Values)
00871                     searchables.Add(p.Info);
00872             }
00873 
00874             return searchables.ToArray();
00875         }
00882         public ISearchable[] ListItems(ResultType type, string creator)
00883         {
00884             List<ISearchable> searchables = new List<ISearchable>();
00885 
00886             if ((type & ResultType.Project) == ResultType.Project)
00887             {
00888                 foreach (Project p in data.ProjectTable.Values)
00889                 {
00890                     if(GetRole(p.ID, creator) != null)
00891                         searchables.Add(p.Info);
00892                 }
00893             }
00894 
00895             if ((type & ResultType.Literature) == ResultType.Literature)
00896             {
00897                 foreach (Literature p in data.LiteratureTable.Values)
00898                     if (p.Creator.UserName == creator)
00899                         searchables.Add(p.Info);
00900             }
00901 
00902             return searchables.ToArray();
00903         }
00904 
00905 
00911         public List<SearchResult> SearchByTag(string tag)
00912         {
00913             TagInfo[] tags = TagInfo.Group(GetTags(tag, -1, null));
00914             List<SearchResult> list = new List<SearchResult>();
00915             Array.Sort<TagInfo>(tags, new TagComparer());
00916             foreach (TagInfo t in tags)
00917             {
00918                 ISearchable i = data.ProjectTable.ContainsKey(t.ID) ? (ISearchable)data.ProjectTable[t.ID].Info : (ISearchable)data.LiteratureTable[t.ID].Info;
00919                 SearchResult sr = new SearchResult(t.Count, i);
00920                 list.Add(sr);
00921             }
00922 
00923             return list;
00924         }
00925         private class TagComparer : IComparer<TagInfo>
00926         {
00927             #region IComparer<TagInfo> Members
00928 
00929             public int Compare(TagInfo x, TagInfo y)
00930             {
00931                 if (x.Count < y.Count)
00932                     return 1;
00933                 if (x.Count > y.Count)
00934                     return -1;
00935                 return 0;
00936             }
00937 
00938             #endregion
00939         }
00940 
00941         private class SearchResultComparer : IComparer<SearchResult>
00942         {
00943             #region IComparer<SearchResult> Members
00944 
00945             public int Compare(SearchResult x, SearchResult y)
00946             {
00947                 if (x.Relevance < y.Relevance)
00948                     return 1;
00949                 if (x.Relevance > y.Relevance)
00950                     return -1;
00951                 return 0;
00952             }
00953 
00954             #endregion
00955         }
00956 
00957         public List<SearchResult> ShowRelated(int id)
00958         {
00959             List<SearchResult> sr = new List<SearchResult>();
00960             Dictionary<int, SearchResult> results = new Dictionary<int, SearchResult>();
00961 
00962             TagInfo[] tags = GetTags(null, id, null);
00963             tags = TagInfo.Group(tags);
00964 
00965             foreach (TagInfo ti in tags)
00966             {
00967                 TagInfo[] tags2 = GetTags(ti.Name, -1, null);
00968                 tags2 = TagInfo.Group(tags2);
00969 
00970                 foreach (TagInfo ti2 in tags2)
00971                 {
00972                     ISearchable i = null;
00973                     if(ti2.ID == id)
00974                         continue;
00975                     
00976                     if(data.ProjectTable.ContainsKey(ti2.ID))
00977                         i = data.ProjectTable[ti2.ID].Info;
00978                     
00979                     if(data.LiteratureTable.ContainsKey(ti2.ID))
00980                         i = data.LiteratureTable[ti2.ID].Info;
00981 
00982                     if(i == null)
00983                         continue;
00984 
00985                     if (results.ContainsKey(ti2.ID))
00986                     {
00987                         results[ti2.ID].Relevance += ti2.Count * ti.Count;
00988                     }
00989                     else
00990                         results.Add(ti2.ID, new SearchResult(ti2.Count * ti.Count, i));
00991 
00992                 }
00993             }
00994             sr.AddRange(results.Values);
00995             sr.Sort(new SearchResultComparer());
00996             return sr;
00997         }
00998 
00999         
01000         #endregion
01001 
01002         #region Tag methods
01003 
01011         public TagInfo[] GetTags(string tag, int id, string username)
01012         {
01013             List<string> query = new List<string>();
01014 
01015             if (!string.IsNullOrEmpty(tag))
01016                 query.Add("Tag = '" + tag.Replace("'", "''") + "'");
01017 
01018             if (id >= 0)
01019                 query.Add("ID = '" + id.ToString() + "'");
01020 
01021             if (!string.IsNullOrEmpty(username))
01022                 query.Add("UserName = '" + username.Replace("'", "''") + "'");
01023 
01024             // Get the tag
01025             DataRow[] rows = data.Tags.Select(String.Join(" AND ", query.ToArray()));
01026             TagInfo[] tags = new TagInfo[rows.Length];
01027             for (int i = 0; i < rows.Length; i++)
01028             {
01029                 tags[i] = new TagInfo(rows[i]["Tag"].ToString(), (int)rows[i]["ID"], rows[i]["UserName"].ToString());
01030             }
01031             return tags;
01032         }
01040         public Messages AddTag(string tag, int id, string username)
01041         {
01042             if (!data.LiteratureTable.ContainsKey(id) && !data.ProjectTable.ContainsKey(id))
01043                 return Messages.Fail;
01044 
01045             // Get the tag
01046             DataRow[] rows = data.Tags.Select("Tag = '" + tag.Replace("'", "''") + "' AND UserName = '" + username.Replace("'", "''") + "' AND ID = '" + id.ToString() + "'");
01047             // if the tag was not found
01048             if (rows.Length == 0)
01049             {
01050                 data.Tags.Rows.Add(tag, id.ToString(), username);
01051                 data.Tags.AcceptChanges();
01052                 SaveData();
01053                 UniqueTagCount = -1;
01054                 return Messages.OK;
01055             }
01056             return Messages.Fail;
01057         }
01065         public Messages RemoveTag(string tag, int id, string username)
01066         {
01067             if (!data.LiteratureTable.ContainsKey(id) && !data.ProjectTable.ContainsKey(id))
01068                 return Messages.Fail;
01069 
01070             // Get the tag
01071             DataRow[] rows = data.Tags.Select("Tag = '" + tag.Replace("'", "''") + "' AND UserName = '" + username.Replace("'", "''") + "' AND ID = '" + id.ToString() + "'");
01072             // if the tag was found
01073             if (rows.Length == 1)
01074             {
01075                 data.Tags.Rows.Remove(rows[0]);
01076                 data.Tags.AcceptChanges();
01077                 SaveData();
01078                 UniqueTagCount = -1;
01079                 return Messages.OK;
01080             }
01081             return Messages.Fail;
01082         }
01083 
01088         private int CalcUniqueTags()
01089         {
01090             if (UniqueTagCount > -1)
01091                 return UniqueTagCount;
01092 
01093             Dictionary<string, int> tags = new Dictionary<string, int>();
01094             foreach (DataRow row in data.Tags.Rows)
01095             {
01096                 if (!tags.ContainsKey(row["Tag"].ToString()))
01097                     tags.Add(row["Tag"].ToString(), 1);
01098                 else
01099                     tags[row["Tag"].ToString()]++;
01100             }
01101             UniqueTagCount = tags.Count;
01102             return tags.Count;
01103         }
01104 
01105         #endregion
01106 
01107         #region Person methods
01108 
01118         public Messages RegisterUser(string user, string password, string name, string department, string email)
01119         {
01120             Person p = GetUser(user);
01121             if (p != null)
01122                 return Messages.UserExists;
01123 
01124             p = new Person(user, password, name, department, email);
01125             data.PersonTable.Add(p.UserName, p);
01126 
01127             database.SaveData(data);
01128 
01129             return Messages.OK;
01130         }
01136         public Person GetUser(string user)
01137         {
01138             if (data.PersonTable.ContainsKey(user))
01139                 return data.PersonTable[user];
01140 
01141             return null;
01142         }
01148         public PersonInfo GetPersonInfo(string username)
01149         {
01150             if (data.PersonTable.ContainsKey(username))
01151             {
01152                 return data.PersonTable[username].Info;
01153 
01154             }
01155             return new PersonInfo();
01156         }
01162         public Messages UpdatePerson(PersonInfo pi)
01163         {
01164             if (!data.PersonTable.ContainsKey(pi.username))
01165                 return Messages.Fail;
01166 
01167             Person p = data.PersonTable[pi.username];
01168             p.Department = pi.department;
01169             p.Email = pi.email;
01170             if (pi.password.Trim().Length > 0)
01171                 p.Password = pi.password;
01172             p.Name = pi.name;
01173             return Messages.OK;
01174         }
01175         
01176 
01177         #endregion
01178 
01179         #region Role methods
01180         
01186         public RoleInfo[] GetRoles(int id)
01187         {
01188             if (!data.ProjectTable.ContainsKey(id))
01189                 return new RoleInfo[0];
01190 
01191             RoleInfo[] infos = new RoleInfo[data.ProjectTable[id].Roles.Count];
01192             for (int i = 0; i < infos.Length; i++)
01193                 infos[i] = data.ProjectTable[id].Roles[i].Info;
01194 
01195             return infos;
01196         }
01204         public Messages AssignUser(string username, int project, RoleType role)
01205         {
01206             if (!data.PersonTable.ContainsKey(username) || !data.ProjectTable.ContainsKey(project))
01207                 return Messages.Fail;
01208 
01209             data.ProjectTable[project].AddPerson(data.PersonTable[username], role);
01210             return Messages.OK;
01211         }
01218         public Messages UnassignUser(string username, int project)
01219         {
01220             if (!data.PersonTable.ContainsKey(username) || !data.ProjectTable.ContainsKey(project))
01221                 return Messages.Fail;
01222 
01223             Role r = data.ProjectTable[project].GetPerson(username);
01224             if (r != null && r.Type != RoleType.Creator)
01225                 data.ProjectTable[project].Roles.Remove(r);
01226             return Messages.OK;
01227         }
01234         public Role GetRole(int project, string username)
01235         {
01236             if (!data.ProjectTable.ContainsKey(project))
01237                 return null;
01238 
01239             return data.ProjectTable[project].GetPerson(username);
01240         }
01241 
01242         #endregion
01243 
01244         #region Statistics method
01249         public StatisticsInfo GetStatistics()
01250         {
01251             return new StatisticsInfo(data.ProjectTable.Count, CalcUniqueTags(), data.Tags.Rows.Count, data.LiteratureTable.Count, data.PersonTable.Count);
01252         }
01253 
01254         #endregion
01255     }
01256 }

Generated on Thu Dec 21 06:21:56 2006 for SCRAML by  doxygen 1.5.1-p1