SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IContentClassElement.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.Globalization;
18 using System.Security;
19 using System.Xml;
20 using erminas.SmartAPI.Exceptions;
21 using erminas.SmartAPI.Utils;
22 
23 namespace erminas.SmartAPI.CMS.Project.ContentClasses.Elements
24 {
26  {
30  ContentClassCategory Category { get; }
31 
35  void CommitInCurrentLanguage();
36 
37  void CommitInLanguage(string languageAbbreviation);
38 
46  new string Name { get; set; }
47 
48  IContentClass ContentClass { get; set; }
49 
70  IContentClassElement CopyToContentClass(IContentClass contentClass);
71 
75  ElementType Type { get; }
76  }
77 
84  internal abstract class ContentClassElement : LanguageDependentPartialRedDotProjectObject, IContentClassElement
85  {
86  private string _originalName;
87 
88  protected ContentClassElement(IContentClass contentClass, XmlElement xmlElement)
89  : base(contentClass.Project, xmlElement)
90  {
91  // CreateAttributes("eltname", LANGUAGEVARIANTID);
92  ContentClass = contentClass;
93  LoadXml();
94  _originalName = Name;
95  }
96 
97  public new string Name { get { return base.Name; } set { base.Name = value; } }
98 
102  public abstract ContentClassCategory Category { get; }
103 
107  public virtual void CommitInCurrentLanguage()
108  {
109  CommitInLanguage(Project.LanguageVariants.Current.Abbreviation);
110  }
111 
112  public virtual void CommitInLanguage(string abbreviation)
113  {
114  //RQL for committing changes
115  //One parameter: xml representation of the element, containing an attribute "action" with value "save"
116  const string COMMIT_ELEMENT = "<TEMPLATE><ELEMENTS>{0}</ELEMENTS></TEMPLATE>";
117 
118  using (new LanguageContext(Project.LanguageVariants[abbreviation]))
119  {
120  var node = GetElementForLanguage(abbreviation).MergedElement;
121  if (Name != _originalName)
122  {
123  node.SetAttributeValue("eltname", SecurityElement.Escape(Name));
124  }
125  XmlDocument rqlResult =
126  ContentClass.Project.ExecuteRQL(string.Format(COMMIT_ELEMENT, GetSaveString(node)),
127  RqlType.SessionKeyInProject);
128  try
129  {
130  var resultElement = (XmlElement) rqlResult.GetElementsByTagName("ELEMENT")[0];
131  string tmpGuidStr = resultElement.Attributes["guid"].Value;
132  var newGuid = new Guid(tmpGuidStr);
133  if (!newGuid.Equals(Guid))
134  {
135  throw new SmartAPIException(Session.ServerLogin, "Unexpected guid in return value");
136  }
137  //if needed could check wether the element has changed on the server, via the checked attribute
138  //-1 = changed 0 = unchanged
139  } catch (Exception e)
140  {
141  throw new SmartAPIException(Session.ServerLogin,
142  string.Format("Could not save changes to {0}", this), e);
143  }
144  }
145  if (Name != _originalName)
146  {
147  _originalName = Name;
148  ContentClass.Elements.InvalidateCache();
149  }
150  }
151 
152  public IContentClass ContentClass { get; set; }
153 
174  public IContentClassElement CopyToContentClass(IContentClass contentClass)
175  {
176  var newContentClassElement = CreateElement(contentClass, Type);
177  var assign = new AttributeAssignment();
178  assign.AssignAllRedDotAttributesForLanguage(this, newContentClassElement,
179  Project.LanguageVariants.Current.Abbreviation);
180 
181  var node = (XmlElement) newContentClassElement.XmlElement.Clone();
182  node.Attributes.RemoveNamedItem("guid");
183  string creationString = GetSaveString(node);
184 
185  // <summary>
186  // RQL for creating an element from a content class.
187  // Two parameters:
188  // 1. Content class guid
189  // 2. Element to create, make sure it contains an attribute "action" with the value "save"!
190  // </summary>
191  const string CREATE_ELEMENT = @"<TEMPLATE guid=""{0}"">{1}</TEMPLATE>";
192 
193  XmlDocument rqlResult =
194  contentClass.Project.ExecuteRQL(string.Format(CREATE_ELEMENT, contentClass.Guid.ToRQLString(),
195  creationString));
196  var resultElementNode = (XmlElement) rqlResult.GetElementsByTagName("ELEMENT")[0];
197  if (resultElementNode == null)
198  {
199  throw new SmartAPIException(Session.ServerLogin,
200  string.Format("Error during creation of element {0}", this));
201  }
202  newContentClassElement.Guid = resultElementNode.GetGuid();
203 
204  return newContentClassElement;
205  }
206 
207  //public new string Name { get { return base.Name; } set { base.Name = value; } }
208 
212  public ElementType Type { get; private set; }
213 
214  protected override void LoadWholeObject()
215  {
216  //TODO sealed?
217  }
218 
219  protected override XmlElement RetrieveWholeObject()
220  {
221  return GetRQLRepresentation(Project, Guid);
222  }
223 
224  internal static IContentClassElement CreateElement(IContentClass contentClass, Guid elementGuid)
225  {
226  var xmlElement = GetRQLRepresentation(contentClass.Project, elementGuid);
227  return CreateElement(contentClass, xmlElement);
228  }
229 
236  internal static ContentClassElement CreateElement(IContentClass contentClass, XmlElement xmlElement)
237  {
238  var type = (ElementType) int.Parse(xmlElement.GetAttributeValue("elttype"));
239  switch (type)
240  {
241  case ElementType.DatabaseContent:
242  return new DatabaseContent(contentClass, xmlElement);
243  case ElementType.TextHtml:
244  return new TextHtml(contentClass, xmlElement);
245  case ElementType.TextAscii:
246  return new TextAscii(contentClass, xmlElement);
247  case ElementType.StandardFieldText:
248  case ElementType.StandardFieldTextLegacy:
249  return new StandardFieldText(contentClass, xmlElement);
250  case ElementType.StandardFieldNumeric:
251  return new StandardFieldNumeric(contentClass, xmlElement);
252  case ElementType.StandardFieldDate:
253  return new StandardFieldDate(contentClass, xmlElement);
254  case ElementType.StandardFieldTime:
255  return new StandardFieldTime(contentClass, xmlElement);
256  case ElementType.StandardFieldUserDefined:
257  return new StandardFieldUserDefined(contentClass, xmlElement);
258  case ElementType.StandardFieldEmail:
259  return new StandardFieldEmail(contentClass, xmlElement);
260  case ElementType.StandardFieldUrl:
261  return new StandardFieldURL(contentClass, xmlElement);
262  case ElementType.Headline:
263  return new Headline(contentClass, xmlElement);
264  case ElementType.Background:
265  return new Background(contentClass, xmlElement);
266  case ElementType.Image:
267  return new Image(contentClass, xmlElement);
268  case ElementType.Media:
269  return new Media(contentClass, xmlElement);
270  case ElementType.ListEntry:
271  return new ListEntry(contentClass, xmlElement);
272  case ElementType.Transfer:
273  return new Transfer(contentClass, xmlElement);
274  case ElementType.Ivw:
275  return new IVW(contentClass, xmlElement);
276  case ElementType.OptionList:
277  return new OptionList(contentClass, xmlElement);
278  case ElementType.Attribute:
279  return new Attribute(contentClass, xmlElement);
280  case ElementType.Info:
281  return new Info(contentClass, xmlElement);
282  case ElementType.Browse:
283  return new Browse(contentClass, xmlElement);
284  case ElementType.Area:
285  return new Area(contentClass, xmlElement);
286  case ElementType.AnchorAsImage:
287  return new ImageAnchor(contentClass, xmlElement);
288  case ElementType.AnchorAsText:
289  return new TextAnchor(contentClass, xmlElement);
290  case ElementType.Container:
291  return new Container(contentClass, xmlElement);
292  case ElementType.Frame:
293  return new Frame(contentClass, xmlElement);
294  case ElementType.SiteMap:
295  return new SiteMap(contentClass, xmlElement);
296  case ElementType.HitList:
297  return new HitList(contentClass, xmlElement);
298  case ElementType.List:
299  return new List(contentClass, xmlElement);
300  case ElementType.ProjectContent:
301  return new ProjectContent(contentClass, xmlElement);
302  case ElementType.ConditionRedDotLiveOrDeliveryServer:
303  return new DeliveryServerConstraint(contentClass, xmlElement);
304  default:
305  throw new ArgumentException("unknown element type: " + type);
306  }
307  }
308 
315  private static ContentClassElement CreateElement(IContentClass contentClass, ElementType elementType)
316  {
317  var doc = new XmlDocument();
318  XmlElement element = doc.CreateElement("ELEMENT");
319  XmlAttribute typeAttr = doc.CreateAttribute("elttype");
320  XmlAttribute guidAttr = doc.CreateAttribute("guid");
321  typeAttr.Value = ((int) elementType).ToString(CultureInfo.InvariantCulture);
322  guidAttr.Value = new Guid().ToRQLString();
323  element.Attributes.Append(typeAttr);
324  element.Attributes.Append(guidAttr);
325 
326  return CreateElement(contentClass, element);
327  }
328 
329  private static XmlElement GetRQLRepresentation(IProject project, Guid ccElementGuid)
330  {
331  const string LOAD_ELEMENT = @"<TEMPLATE><ELEMENT action=""load"" guid=""{0}""/></TEMPLATE>";
332  return project.ExecuteRQL(LOAD_ELEMENT.RQLFormat(ccElementGuid)).GetSingleElement("ELEMENT");
333  }
334 
335  private void LoadXml()
336  {
337  _name = _xmlElement.GetAttributeValue("eltname");
338  Type = (ElementType) _xmlElement.GetIntAttributeValue("elttype").GetValueOrDefault();
339  }
340  }
341 
346  {
347  Content,
348  Structural,
349  Meta
350  }
351 }