SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IClipboard.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.Collections.Generic;
18 using System.Linq;
19 using System.Xml;
20 using erminas.SmartAPI.CMS.Project.ContentClasses;
21 using erminas.SmartAPI.CMS.Project.Folder;
22 using erminas.SmartAPI.CMS.Project.Pages;
23 using erminas.SmartAPI.CMS.Project.Pages.Elements;
24 using erminas.SmartAPI.Exceptions;
25 using erminas.SmartAPI.Utils;
26 using erminas.SmartAPI.Utils.CachedCollections;
27 
28 namespace erminas.SmartAPI.CMS.Project
29 {
30  public interface IClipboard : ISessionObject
31  {
32  IEnumerable<ISessionObject> Content { get; }
33 
34  IEnumerable<IClipboardEntry> ClipboardEntries { get; }
35  }
36 
38  {
39  new IEnumerable<IProjectObject> Content { get; }
40 
41  IEnumerable<IPage> Pages { get; }
42 
43  IEnumerable<IFolder> Folders { get; }
44 
45  IEnumerable<IPageElement> PageElements { get; }
46 
47  void Add(params IPage[] page);
48 
49  void Add(params IFolder[] folder);
50 
51  void Add(params IContentClass[] contentClass);
52 
53  void Add(params IPageElement[] pageElement);
54 
55  void Remove(params IPage[] page);
56 
57  void Remove(params IFolder[] folder);
58 
59  void Remove(params IContentClass[] contentClass);
60 
61  void Remove(params IPageElement[] pageElement);
62  }
63 
64  public interface IClipboardEntry
65  {
66  Guid Guid { get; }
67 
68  String Type { get; }
69  }
70 
72  {
73  public Guid Guid { get; internal set; }
74 
75  public String Type { get; internal set; }
76  }
77 
78  internal class ProjectClipboard : IProjectClipboard, ICached
79  {
80  private const string SINGLE_ENTRY = @"<DATA guid=""{0}"" type=""{1}"" />";
81  private readonly IProject _project;
82  private List<ClipboardEntry> _clipboardEntries;
83  private IList<IProjectObject> _content;
84 
85  internal ProjectClipboard(IProject project)
86  {
87  _project = project;
88  }
89 
90  public void InvalidateCache()
91  {
92  _clipboardEntries = null;
93  }
94 
95  public void Refresh()
96  {
97  InvalidateCache();
98  EnsureContentIsLoaded();
99  }
100 
101  public ISession Session
102  {
103  get { return _project.Session; }
104  }
105 
106  public IEnumerable<IProjectObject> Content
107  {
108  get
109  {
110  EnsureContentIsLoaded();
111  return _content;
112  }
113  }
114 
115  public IEnumerable<IClipboardEntry> ClipboardEntries
116  {
117  get
118  {
119  EnsureContentIsLoaded();
120  return _clipboardEntries.AsReadOnly(); }
121  }
122 
123  IEnumerable<ISessionObject> IClipboard.Content
124  {
125  get { return _content; }
126  }
127 
128  public IProject Project
129  {
130  get { return _project; }
131  }
132 
133  public IEnumerable<IPage> Pages
134  {
135  get
136  {
137  return Content.Where(x => x is IPage)
138  .Cast<IPage>();
139  }
140  }
141 
142  public IEnumerable<IFolder> Folders
143  {
144  get
145  {
146  return Content.Where(x => x is IFolder)
147  .Cast<IFolder>();
148  }
149  }
150 
151  public IEnumerable<IPageElement> PageElements
152  {
153  get
154  {
155  return Content.Where(x => x is IPageElement)
156  .Cast<IPageElement>();
157  }
158  }
159 
160  public void Add(params IPage[] pages)
161  {
162  GenericAdd(pages, "page");
163  }
164 
165  public void Add(params IFolder[] folders)
166  {
167  GenericAdd(folders.Where(IS_SUB_FOLDER).ToArray(), "project.6055");
168  GenericAdd(folders.Where(x => !IS_SUB_FOLDER(x)).ToArray(), "project.6050");
169  }
170 
171  private static readonly Func<IFolder, bool> IS_SUB_FOLDER = x=>x.IsAssetManager && ((IAssetManagerFolder)x).IsSubFolder;
172 
173 
174  public void Add(params IContentClass[] contentClasses)
175  {
176  GenericAdd(contentClasses, "app.4015");
177  }
178 
179  public void Add(params IPageElement[] pageElements)
180  {
181  GenericAdd(pageElements, "pageelement");
182  }
183 
184  public void Remove(params IPage[] pages)
185  {
186  GenericRemove(pages, "page");
187  }
188 
189  public void Remove(params IFolder[] folders)
190  {
191  GenericRemove(folders.Where(IS_SUB_FOLDER).ToArray(), "project.6055");
192  GenericRemove(folders.Where(x => !IS_SUB_FOLDER(x)).ToArray(), "project.6050");
193  }
194 
195  public void Remove(params IContentClass[] contentClasses)
196  {
197  GenericRemove(contentClasses, "app.4015");
198  }
199 
200  public void Remove(params IPageElement[] pageElements)
201  {
202  GenericRemove(pageElements, "pageelement");
203  }
204 
205  private void EnsureContentIsLoaded()
206  {
207  if (_clipboardEntries != null)
208  {
209  return;
210  }
211 
212  const string LOAD_CLIPBOARD =
213  @"<ADMINISTRATION><USER guid=""{0}""><CLIPBOARDDATA action=""load"" projectguid=""{1}"" foraspx=""1"" /></USER></ADMINISTRATION>";
214 
215  var doc =
216  Project.ExecuteRQL(LOAD_CLIPBOARD.RQLFormat(Session.CurrentUser, Project, Project.LanguageVariants.Current.Abbreviation));
217 
218  var entries = doc.GetElementsByTagName("DATA");
219  _clipboardEntries = entries.Cast<XmlElement>().Select(x => new ClipboardEntry{Guid = x.GetGuid(), Type = x.GetAttributeValue("type")}).ToList();
220 
221  _content = _clipboardEntries.Select(CreateContentEntry)
222  .Where(x => x != null)
223  .ToList();
224  }
225 
226  private IProjectObject CreateContentEntry(IClipboardEntry clipboardEntry)
227  {
228  switch (clipboardEntry.Type)
229  {
230  case "page":
231  return new Page(Project, clipboardEntry.Guid, Project.LanguageVariants.Current);
232  case "pageelement":
233  return PageElementFactory.Instance.CreateElement(Project, clipboardEntry.Guid, Project.LanguageVariants.Current);
234  case "app.4015":
235  return new ContentClass(Project, clipboardEntry.Guid);
236  case "project.6050":
237  IFolder folder;
238  return Project.Folders.TryGetByGuid(clipboardEntry.Guid, out folder) ? folder : null;
239  case "project.6055":
240  IFolder subFolder;
241  return Project.Folders.AllIncludingSubFolders.TryGetByGuid(clipboardEntry.Guid, out subFolder) ? subFolder : null;
242  default:
243  return null;
244  }
245  }
246 
247  private void GenericAdd(IRedDotObject[] entries, string type)
248  {
249  if (entries == null || entries.Length == 0)
250  {
251  return;
252  }
253 
254  const string ADD_ENTRY =
255  @"<ADMINISTRATION><USER guid=""{0}""><CLIPBOARDDATA action=""add"" projectguid=""{1}"">{2}</CLIPBOARDDATA></USER></ADMINISTRATION>";
256 
257  var entryStr = string.Join("", entries.Select(x => SINGLE_ENTRY.RQLFormat(x, type)));
258 
259  var doc = Session.ExecuteRQL(ADD_ENTRY.RQLFormat(Session.CurrentUser, Project, entryStr), RQL.IODataFormat.SessionKeyAndLogonGuid);
260 
261  //if (!doc.InnerText.Contains("ok"))
262  //{
263  // throw new SmartAPIException(Session.ServerLogin, "Error adding entries to clipboard");
264  //}
265 
266  InvalidateCache();
267  }
268 
269  private void GenericRemove(IProjectObject[] entries, string type)
270  {
271  if (entries == null || entries.Length == 0)
272  {
273  return;
274  }
275 
276  const string REMOVE_ENTRY =
277  @"<ADMINISTRATION><USER guid=""{0}""><CLIPBOARDDATA action=""remove"" projectguid=""{1}"">{2}</CLIPBOARDDATA></USER></ADMINISTRATION>";
278 
279  var entryStr = string.Join("", entries.Select(x => SINGLE_ENTRY.RQLFormat(x, type)));
280 
281  var doc = Project.ExecuteRQL(REMOVE_ENTRY.RQLFormat(Session.CurrentUser, Project, entryStr));
282 
283  if (!doc.InnerText.Contains("ok"))
284  {
285  throw new SmartAPIException(Session.ServerLogin, "Error removing entries from clipboard");
286  }
287 
288  InvalidateCache();
289  }
290  }
291 }