SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IKeyword.cs
Go to the documentation of this file.
1 // SmartAPI - .Net programmatic access to RedDot servers
2 //
3 // Copyright (C) 2013 erminas GbR
4 //
5 // This program is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free Software Foundation,
7 // either version 3 of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 // See the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program.
14 // If not, see <http://www.gnu.org/licenses/>.
15 
16 using System;
17 using System.Web;
18 using System.Xml;
19 using erminas.SmartAPI.Exceptions;
20 using erminas.SmartAPI.Utils;
21 
22 namespace erminas.SmartAPI.CMS.Project.Keywords
23 {
25  {
26  ICategory Category { get; }
27  void Commit();
28 
33  void Delete();
34 
40  void DeleteForcibly();
41 
42  void Rename(string newKeywordName);
43  }
44 
45  public static class KeywordFactory
46  {
47  public static IKeyword CreateFromGuid(IProject project, Guid guid)
48  {
49  return new Keyword(project, guid);
50  }
51  }
52 
53  internal class Keyword : PartialRedDotProjectObject, IKeyword
54  {
55  private ICategory _category;
56 
57  internal Keyword(IProject project, XmlElement xmlElement) : base(project, xmlElement)
58  {
59  LoadXml();
60  }
61 
62  internal Keyword(IProject project, Guid guid) : base(project, guid)
63  {
64  }
65 
66  public ICategory Category
67  {
68  get { return LazyLoad(ref _category); }
69  internal set { _category = value; }
70  }
71 
72  public void Commit()
73  {
74  const string SAVE_KEYWORD = @"<PROJECT><KEYWORD action=""save"" guid=""{0}"" value=""{1}""/></PROJECT>";
75 
76  string htmlEncodedName = HttpUtility.HtmlEncode(Name);
77  var xmlDoc = Project.ExecuteRQL(SAVE_KEYWORD.RQLFormat(this, htmlEncodedName));
78 
79  const string KEYWORD_XPATH_TEMPLATE = "/IODATA/KEYWORD[@value='{0}' and @guid='{1}']";
80  string keywordXPath = KEYWORD_XPATH_TEMPLATE.RQLFormat(htmlEncodedName, this);
81  var keyword = xmlDoc.SelectSingleNode(keywordXPath);
82  if (keyword == null)
83  {
84  throw new SmartAPIException(Session.ServerLogin,
85  string.Format("Could not rename keyword to '{0}'", Name));
86  }
87  }
88 
89  public void Delete()
90  {
91  const string DELETE_KEYWORD = @"<KEYWORD action=""delete"" guid=""{0}"" force=""0""/>";
92 
93  var xmlDoc = Project.ExecuteRQL(DELETE_KEYWORD.RQLFormat(this), RqlType.SessionKeyInProject);
94  var keyword = (XmlElement) xmlDoc.SelectSingleNode("/IODATA/KEYWORD");
95 
96  if (keyword == null)
97  {
98  throw new SmartAPIException(Session.ServerLogin, string.Format("Could not delete keyword {0}", this));
99  }
100 
101  if (IsKeywordStillUsed(keyword))
102  {
103  throw new SmartAPIException(Session.ServerLogin,
104  string.Format(
105  "Could not delete keyword {0}, because it is still used for page connections",
106  this));
107  }
108 
109  Category.Keywords.InvalidateCache();
110  }
111 
112  public void DeleteForcibly()
113  {
114  const string DELETE_KEYWORD = @"<KEYWORD action=""delete"" guid=""{0}"" force=""1"" password=""{1}"" />";
115 
116  var xmlDoc =
117  Project.ExecuteRQL(DELETE_KEYWORD.RQLFormat(this, Project.Session.ServerLogin.AuthData.Password),
118  RqlType.SessionKeyInProject);
119  var keyword = (XmlElement) xmlDoc.SelectSingleNode("/IODATA/KEYWORD");
120  //TODO execute page builder command
121  if (keyword == null)
122  {
123  throw new SmartAPIException(Session.ServerLogin, string.Format("Could not delete keyword {0}", this));
124  }
125 
126  Category.Keywords.InvalidateCache();
127  }
128 
129  public void Rename(string newKeywordName)
130  {
131  var oldName = Name;
132  Name = newKeywordName;
133  try
134  {
135  Commit();
136  } catch (Exception)
137  {
138  Name = oldName;
139  throw;
140  }
141  }
142 
143  protected override void LoadWholeObject()
144  {
145  LoadXml();
146  }
147 
148  protected override XmlElement RetrieveWholeObject()
149  {
150  const string LOAD_KEYWORD =
151  @"<PROJECT><CATEGORY><KEYWORD action=""load"" guid=""{0}""/></CATEGORY></PROJECT>";
152  return (XmlElement) Project.ExecuteRQL(LOAD_KEYWORD.RQLFormat(this)).GetElementsByTagName("KEYWORD")[0];
153  }
154 
155  private static bool IsKeywordStillUsed(XmlElement keyword)
156  {
157  return keyword.GetIntAttributeValue("countkeywordonpag").GetValueOrDefault() > 0 ||
158  keyword.GetIntAttributeValue("countkeywordonpge") > 0 ||
159  keyword.GetIntAttributeValue("countkeywordonpgeandpag") > 0;
160  }
161 
162  private void LoadXml()
163  {
164  Name = _xmlElement.GetAttributeValue("value");
165  InitIfPresent(ref _category, "categoryguid", x => new Category(Project, Guid.Parse(x)));
166  if (_category == null)
167  {
168  var keywordsNode = XmlElement.ParentNode as XmlElement;
169  if (keywordsNode == null)
170  {
171  return;
172  }
173  var categoryNode = keywordsNode.ParentNode as XmlElement;
174  if (categoryNode == null || categoryNode.Name != "CATEGORY")
175  {
176  return;
177  }
178 
179  _category = new Category(Project, categoryNode);
180  }
181  }
182  }
183 }