2using System.Collections.Generic;
4using System.Threading.Tasks;
25 private DirectoryInfo dirInfo;
26 private string folderName;
27 private string folderLocalName;
28 private DateTime? created;
29 private DateTime? updated;
35 : this(string.Empty, null, null, null)
50 this.created = Created;
51 this.updated = Updated;
53 if (
string.IsNullOrEmpty(this.folderName))
56 this.folderLocalName =
null;
60 this.dirInfo =
new DirectoryInfo(this.folderName);
61 this.folderLocalName = Path.GetFileName(this.folderName);
68 [Page(7,
"File System", 100)]
69 [Header(8,
"Folder:")]
70 [ToolTip(9,
"Local path to folder.")]
74 get => this.folderLocalName;
77 if (this.folderLocalName != value)
79 if (this.parent is
null)
80 throw new Exception(
"You are not allowed to change the folder name.");
82 string FullPath = Path.Combine(this.parent.folderName, value);
83 if (!FullPath.StartsWith(
this.parent.FolderName, StringComparison.CurrentCultureIgnoreCase))
84 throw new Exception(
"Invalid local folder name.");
86 if (!
string.IsNullOrEmpty(this.folderName))
88 if (Directory.Exists(FullPath) || File.Exists(FullPath))
89 throw new Exception(
"Folder or file already exists.");
91 Directory.Move(this.folderName, FullPath);
94 this.folderLocalName = value;
95 this.folderName = FullPath;
96 this.dirInfo =
new DirectoryInfo(FullPath);
104 [Page(7,
"File System", 100)]
105 [Header(10,
"Full Path:")]
106 [ToolTip(11,
"Full path to folder.")]
128 public string LocalId => this.folderLocalName;
133 public string LogId => this.folderName;
151 if (this.dirInfo is
null || !this.dirInfo.Exists)
154 DirectoryInfo[] Directories = this.dirInfo.GetDirectories();
155 if (Directories.Length > 0)
158 FileInfo[] Files = this.dirInfo.GetFiles();
159 if (Files.Length > 0)
194 public DateTime
LastChanged => File.GetLastWriteTimeUtc(this.folderName);
243 if (this.parent is
null)
249 internal void FolderUpdated()
263 LinkedList<Parameter> Parameters =
new LinkedList<Parameter>();
265 if (this.created is
null)
269 this.created = Directory.GetCreationTimeUtc(this.folderName);
277 if (this.updated is
null)
281 this.updated = Directory.GetLastWriteTimeUtc(this.folderName);
289 if (this.created.HasValue)
292 this.created.Value));
294 if (this.updated.HasValue &&
this.updated.Value >
this.created.Value)
297 this.updated.Value));
310 return Task.FromResult<IEnumerable<Message>>(
null);
335 return Task.FromResult(
true);
338 return Task.FromResult(
false);
340 if (this.parent is
null &&
string.IsNullOrEmpty(this.folderName))
341 this.parent = ParentFolder;
343 return Task.FromResult(
true);
364 if (
string.IsNullOrEmpty(ChildFolder.FolderName))
365 throw new Exception(
"Folder name is empty.");
367 if (!ChildFolder.FolderName.StartsWith(
this.folderName))
368 throw new Exception(
"Invalid parent folder.");
370 if (!Directory.Exists(ChildFolder.FolderName))
371 Directory.CreateDirectory(ChildFolder.FolderName);
375 if (
string.IsNullOrEmpty(ChildFile.FileName))
376 throw new Exception(
"File name is empty.");
378 if (!ChildFile.FileName.StartsWith(
this.folderName))
379 throw new Exception(
"Invalid parent folder.");
381 if (!File.Exists(ChildFile.FileName))
383 FileStream fs = File.Create(ChildFile.FileName);
388 throw new Exception(
"Unable to add child node.");
390 return Task.CompletedTask;
410 if (this.parent is
null)
411 throw new UnauthorizedAccessException(
"Folder is protected against deletion.");
413 if (Directory.Exists(
this.folderName))
414 Directory.Delete(this.folderName,
true);
416 return Task.CompletedTask;
426 return Task.FromResult<IEnumerable<ICommand>>(
new ICommand[]
434 new CreateTextFileCommand(
this,
"text/cssx",
".cssx", 41,
"Create CSSX File...",
"CreateCssxFile",
"6"),
436 new CreateTextFileCommand(
this,
"application/x-webscript",
".ws", 39,
"Create Webscript File...",
"CreateWsFile",
"8")
447 List<ControlParameter> Parameters =
new List<ControlParameter>();
448 DirectoryInfo Info =
new DirectoryInfo(this.FolderName);
449 FileAttributes Attributes = Info.Attributes;
457 GetReadOnly, SetReadOnly));
462 GetHidden, SetHidden));
467 GetSystem, SetSystem));
472 GetArchive, SetArchive));
474 return Parameters.ToArray();
479 return GetAttribute(Node, FileAttributes.ReadOnly);
484 return SetAttribute(Node, Value, FileAttributes.ReadOnly);
489 return GetAttribute(Node, FileAttributes.Hidden);
494 return SetAttribute(Node, Value, FileAttributes.Hidden);
499 return GetAttribute(Node, FileAttributes.System);
504 return SetAttribute(Node, Value, FileAttributes.System);
509 return GetAttribute(Node, FileAttributes.Archive);
514 return SetAttribute(Node, Value, FileAttributes.Archive);
517 private static Task<bool?> GetAttribute(
IThingReference Node, FileAttributes Attribute)
520 return Task.FromResult<
bool?>(
null);
522 FileAttributes Attr = FolderNode.dirInfo.Attributes;
524 return Task.FromResult<
bool?>(Attr.HasFlag(Attribute));
527 private static Task SetAttribute(
IThingReference Node,
bool Value, FileAttributes Attribute)
530 throw new ArgumentException(
"Unexpected node type.", nameof(Node));
532 FileAttributes Attr = FolderNode.dirInfo.Attributes;
533 FileAttributes Bak = Attr;
541 FolderNode.dirInfo.Attributes = Attr;
543 return Task.CompletedTask;
const string ContentType
Content-Type for CSS files.
const string DefaultContentType
Default Content-Type for HTML: text/html
JavaScript encoder/decoder.
const string DefaultContentType
application/javascript
const string ContentType
Markdown content type.
Plain text encoder/decoder.
const string DefaultContentType
text/plain
const string DefaultContentType
Default content type for XML documents.
Contains information about a language.
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
async Task< Namespace > GetNamespaceAsync(string Name)
Gets the namespace object, given its name, if available.
Contains information about a namespace in a language.
Task< LanguageString > GetStringAsync(int Id)
Gets the string object, given its ID, if available.
Basic access point for runtime language localization.
static async Task< Language > GetDefaultLanguageAsync()
Gets the default language.
Creates a subfolder in a folder.
Creates a text file in a folder.
Reference to a file in the ProgramData folder of the broker.
Reference to a folder in the ProgramData folder of the broker.
Task< bool > RemoveAsync(INode Child)
Removes a child from the node.
bool HasChildren
If the source has any child sources.
bool ChildrenOrdered
If the children of the node have an intrinsic order (true), or if the order is not important (false).
string FolderLocalName
Local folder name
Task DestroyAsync()
Destroys the node. If it is a child to a parent node, it is removed from the parent first.
NodeState State
Current overall state of the node.
ProgramDataFolder()
Reference to a folder in the ProgramData folder of the broker.
ProgramDataFolder(string FolderName, ProgramDataFolder Parent, DateTime? Created, DateTime? Updated)
Reference to a folder in the ProgramData folder of the broker.
Task< string > GetTypeNameAsync(Language Language)
Gets the type name of the node.
string LogId
If provided, an ID for the node, as it would appear or be used in system logs. Can be null,...
string LocalId
If provided, an ID for the node, but unique locally between siblings. Can be null,...
async Task< IEnumerable< Parameter > > GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
Gets displayable parameters.
bool HasCommands
If the node has registered commands or not.
async Task< ControlParameter[]> GetControlParameters()
Get control parameters for the actuator.
Task< bool > CanAddAsync(RequestOrigin Caller)
If the node can be added to by the caller.
Task< bool > CanViewAsync(RequestOrigin Caller)
If the node is visible to the caller.
string SourceId
Optional ID of source containing node.
DateTime LastChanged
When the node was last updated.
Task AddAsync(INode Child)
Adds a new child to the node.
Task< bool > CanEditAsync(RequestOrigin Caller)
If the node can be edited by the caller.
Task< bool > MoveDownAsync(RequestOrigin Caller)
Tries to move the node down.
Task UpdateAsync()
Updates the node (in persisted storage).
Task< IEnumerable< Message > > GetMessagesAsync(RequestOrigin Caller)
Gets messages logged on the node.
string FolderName
Full Folder name.
string Partition
Optional partition in which the Node ID is unique.
Task< bool > AcceptsChildAsync(INode Child)
If the node accepts a presumptive child, i.e. can receive as a child (if that child accepts the node ...
Task< IEnumerable< INode > > ChildNodes
Child nodes. If no child nodes are available, null is returned.
Task< bool > AcceptsParentAsync(INode Parent)
If the node accepts a presumptive parent, i.e. can be added to that parent (if that parent accepts th...
Task< bool > MoveUpAsync(RequestOrigin Caller)
Tries to move the node up.
Task< IEnumerable< ICommand > > Commands
Available command objects. If no commands are available, null is returned.
bool IsReadable
If the node can be read.
INode Parent
Parent Node, or null if a root node.
bool IsControllable
If the node can be controlled.
async Task< bool > CanDestroyAsync(RequestOrigin Caller)
If the node can be destroyed to by the caller.
Data source mirroring the ProgramData folder for the broker.
static IEnumerable< INode > GetChildNodes(ProgramDataFolder FolderNode, string FolderPath)
Gets a set of program data child nodes, for a folder.
const string ProgramDataSourceID
Data Source ID for the ProgramData source.
Service Module hosting the XMPP broker and its components.
Boolean control parameter.
DateTime-valued parameter.
Tokens available in request.
string From
Address of caller.
Interface for actuator nodes.
Interface for nodes that are published through the concentrator interface.
Interface for thing references.
NodeState
State of a node.