17 using System.Collections.Generic;
20 using erminas.SmartAPI.CMS.Project.ContentClasses;
21 using erminas.SmartAPI.CMS.Project.Workflows;
22 using erminas.SmartAPI.CMS.ServerManagement;
23 using erminas.SmartAPI.Exceptions;
24 using erminas.SmartAPI.Utils;
26 namespace erminas.SmartAPI.CMS.Project.Pages
44 List<ResultGroup> Execute();
45 List<IPageSearchFilter> Filters {
get; }
49 int MaxHits {
get;
set; }
55 internal class ExtendedPageSearch : IExtendedPageSearch
57 private readonly List<IPageSearchFilter> _filters =
new List<IPageSearchFilter>();
61 public ExtendedPageSearch(
IProject project)
68 XmlDocument xmlDoc = RunQuery(
true);
70 ((XmlElement) xmlDoc.GetElementsByTagName(
"PAGES")[0]).GetIntAttributeValue(
"hits").GetValueOrDefault();
73 public List<ResultGroup> Execute()
75 return ToResult(RunQuery(
false));
78 public List<IPageSearchFilter> Filters
80 get {
return _filters; }
87 public ILanguageVariant LanguageVariant {
get;
set; }
89 public int MaxHits {
get;
set; }
95 public IProject Project
97 get {
return _project; }
100 public ISession Session
102 get {
return Project.Session; }
105 public IUser User {
get;
set; }
107 private static string GroupByTypeToString(
GroupBy type)
112 return "contentclass";
120 throw new ArgumentException(String.Format(
"Unknown group by type: {0}", type));
124 private ILanguageVariant LanguageVariantOfSearchResults
126 get {
return LanguageVariant ?? _project.LanguageVariants.Current; }
129 private static string OrderByTypeToString(
OrderBy order)
142 return "contentclass";
144 throw new ArgumentException(String.Format(
"Unknown sort direction: {0}", order));
148 private XmlDocument RunQuery(
bool isCountOnly)
150 if (Session.ServerVersion <
new Version(10, 0) && Filters.Any(filter => filter is WorkflowFilter))
153 "Searches for pages in workflow are not supported for RedDot servers with version < 10");
155 const string XSEARCH =
@"<PAGE action=""xsearch"" {0}>{1}</PAGE>";
156 string arguments =
"";
159 arguments +=
"groupby=\"" + GroupByTypeToString(
GroupBy) +
"\" ";
160 arguments +=
"groupdirection=\"" + SortDirectionToString(GroupSortDirection) +
"\" ";
163 if (LanguageVariant != null)
165 arguments +=
"languagevariantid=\"" + LanguageVariant.Abbreviation +
"\" ";
170 arguments +=
@"option=""countresults"" ";
173 arguments +=
"maxhits=\"" + MaxHits +
"\" ";
174 arguments +=
"orderby=\"" + OrderByTypeToString(
OrderBy) +
"\" ";
175 arguments +=
"orderdirection=\"" + SortDirectionToString(OrderDirection) +
"\" ";
176 arguments +=
"pagesize=\"-1\" ";
178 arguments +=
"projectguid=\"" + _project.Guid.ToRQLString() +
"\" ";
181 arguments +=
"userguid=\"" + User.Guid.ToRQLString() +
"\" ";
184 string searchItems =
"";
187 searchItems =
"<SEARCHITEMS>";
188 searchItems += Filters.Aggregate(
"", (value, curPred) => value + curPred.ToSearchItemString());
189 searchItems +=
"</SEARCHITEMS>";
192 return _project.ExecuteRQL(
string.Format(XSEARCH, arguments, searchItems));
195 private static string SortDirectionToString(
SortDirection dir)
204 throw new ArgumentException(String.Format(
"Unknown sort direction: {0}", dir));
208 private IEnumerable<ReleaseInfo> ToReleases(XmlElement releases)
210 return (from XmlElement curRelease in releases
211 let users = curRelease.GetElementsByTagName(
"USER")
213 new ReleaseInfo(curRelease.GetIntAttributeValue(
"assentcount").GetValueOrDefault(),
214 curRelease.GetIntAttributeValue(
"requiredassentcount").GetValueOrDefault(),
215 from XmlElement curUser in releases.GetElementsByTagName(
"USER")
216 select
new ReleaseInfo.UserInfo(_project, curUser))).ToList();
219 private List<ResultGroup> ToResult(XmlDocument doc)
221 XmlNodeList groups = doc.GetElementsByTagName(
"GROUP");
222 if (groups.Count == 0)
224 return new List<ResultGroup> {
new ResultGroup(null, ToResult(doc.GetElementsByTagName(
"PAGE")))};
226 return (from XmlElement curGroup in groups
228 new ResultGroup(curGroup.GetAttributeValue(
"value"),
229 ToResult(curGroup.GetElementsByTagName(
"PAGE")))).ToList();
232 private IEnumerable<Result> ToResult(XmlNodeList pages)
234 return (from XmlElement curPage in pages
235 let creation = (XmlElement) curPage.GetElementsByTagName(
"CREATION")[0]
236 let change = (XmlElement) curPage.GetElementsByTagName(
"CHANGE")[0]
237 let release = (XmlElement) curPage.GetElementsByTagName(
"RELEASE")[0]
238 let contentClass = (XmlElement) curPage.GetElementsByTagName(
"CONTENTCLASS")[0]
241 new Page(_project, curPage.GetGuid(), LanguageVariantOfSearchResults)
243 Id = curPage.GetIntAttributeValue(
"id").GetValueOrDefault(),
244 InitialHeadlineValue = curPage.GetAttributeValue(
"headline"),
245 Status = ((
PageState)
int.Parse(curPage.GetAttributeValue(
"status")))
248 creation.GetOADate().Value,
249 new User(_project.Session, ((XmlElement) creation.GetElementsByTagName(
"USER")[0]).GetGuid()),
250 change.GetOADate().Value,
251 new User(_project.Session, ((XmlElement) change.GetElementsByTagName(
"USER")[0]).GetGuid()),
252 new ContentClass(_project, contentClass.GetGuid())
254 Name = contentClass.GetAttributeValue(
"name")
257 WorkflowInfo = ToWorkflow(curPage.GetElementsByTagName(
"WORKFLOW"))
261 private WorkflowInfo ToWorkflow(XmlNodeList workflows)
263 if (workflows.Count == 0)
268 var workflowElement = (XmlElement) workflows[0];
269 int? skipable = workflowElement.GetIntAttributeValue(
"skipable");
270 var workflow =
new Workflow(_project, workflowElement.GetGuid())
272 Name = workflowElement.GetAttributeValue(
"name")
274 return new WorkflowInfo(workflow,
275 ToReleases((XmlElement) workflowElement.GetElementsByTagName(
"RELEASES")[0]),
276 workflowElement.GetAttributeValue(
"releasename"),
277 (WorkflowInfo.Rejection) workflowElement.GetIntAttributeValue(
"rejectiontype"),
278 (WorkflowInfo.ReleaseType) workflowElement.GetIntAttributeValue(
"releasetype"),
280 ? WorkflowInfo.RejectionSkippableType.NotApplicable
281 : (WorkflowInfo.RejectionSkippableType) skipable.Value,
282 workflowElement.GetIntAttributeValue(
"escalationtimeout").Value,
283 from XmlElement curSupplement in workflowElement.GetElementsByTagName(
"SUPPLEMENT")
284 select
new Note(workflow, curSupplement));