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
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
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
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
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
01046 DataRow[] rows = data.Tags.Select("Tag = '" + tag.Replace("'", "''") + "' AND UserName = '" + username.Replace("'", "''") + "' AND ID = '" + id.ToString() + "'");
01047
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
01071 DataRow[] rows = data.Tags.Select("Tag = '" + tag.Replace("'", "''") + "' AND UserName = '" + username.Replace("'", "''") + "' AND ID = '" + id.ToString() + "'");
01072
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 }