blob: 223c259bb7f039b0cb616ec2e3cf9e5042ddda2a [file] [log] [blame]
using System;
using System.Linq;
using System.Xml;
using System.Runtime;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
/* Copyright (c) 2018-2019 Festo AG & Co. KG <https://www.festo.com/net/de_de/Forms/web/contact_international>, author: Michael Hoffmeister
This software is licensed under the Eclipse Public License - v 2.0 (EPL-2.0) (see https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt).
The browser functionality is under the cefSharp license (see https://raw.githubusercontent.com/cefsharp/CefSharp/master/LICENSE).
The JSON serialization is under the MIT license (see https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md). */
namespace AdminShellNS
{
public class UriIdentifierRepository {
public class Entry
{
public string uri = "";
public string purpose = "";
}
public class Repository
{
public string uriTemplate = "http://smart.festo.com/id/instance/999#######################";
public int lastIndex = 1;
public List<Entry> entries = new List<Entry>() ;
}
private Repository repository = new Repository() ;
private string workingFn = "";
private string lastOTP = "";
private int otpCounter = 1;
private static readonly Random getrandom = new Random();
public bool InitRepository(string fn, string uriTemplate=null) {
repository = new Repository() ;
if (uriTemplate != null)
repository.uriTemplate = uriTemplate ;
return this.Save(fn);
}
public bool Load(string fn)
{
try
{
// try open, see what happens ..
var s = new StreamReader(fn);
var serializer = new XmlSerializer(repository.GetType());
repository = (Repository) serializer.Deserialize(s);
s.Close();
}
catch (Exception ex)
{
Console.Error.WriteLine("When loading " + workingFn + " exception:" + ex.Message);
return false;
}
// looks good
workingFn = fn;
return true;
}
public bool Save(string fn=null) {
if (fn != null)
workingFn = fn ;
try {
var s = new StreamWriter(workingFn) ;
var serializer = new XmlSerializer(repository.GetType());
serializer.Serialize(s, repository);
s.Close() ;
} catch (Exception ex)
{
Console.Error.WriteLine("When saving " + workingFn + " exception:" + ex.Message);
return false;
}
return true;
}
public Entry FindUri(string uri)
{
foreach (var e in repository.entries)
if (e.uri == uri)
return e;
return null;
}
public Entry FindPurpose(string purpose)
{
foreach (var e in repository.entries)
if (e.purpose == purpose)
return e;
return null;
}
public string CreateOrRetrieveUri(string purpose) {
// prepare purpose
purpose = purpose.ToLower() ;
var cleanPurpose = Regex.Replace(purpose, @"[^a-zA-Z0-9\-_]", "");
// check if we have
Entry found = FindPurpose(cleanPurpose) ;
if (found != null)
return found.uri;
// count '#' in template
int digits = repository.uriTemplate.Count(c => c == '#') ;
if (digits<1)
return null;
// no, we have to build a new uri ..
var i = repository.lastIndex;
var uriFree = "";
var newIndex = false ;
while (true) {
// left padded i
var id = (""+i).PadLeft(digits, '0') ;
// replace '#'
var uri = new StringBuilder(repository.uriTemplate) ;
int j = 0 ;
for (int ii=0; ii<uri.Length; ii++)
if (uri[ii] == '#') {
uri[ii] = id[j] ;
j++;
}
uriFree = uri.ToString();
// is this free
if (FindUri(uriFree) == null)
break;
// increment
i++ ;
repository.lastIndex = i;
newIndex = true;
}
// assume: uriFree is OK
var en = new Entry();
en.uri = uriFree;
en.purpose = cleanPurpose;
repository.entries.Add(en);
// be paranoid
if (newIndex)
Save() ;
// nice!
return en.uri;
}
public string CreateOneTimeId() {
// make up this otp
var otp = DateTime.Now.ToString("yyyyMMddHHmmss");
// reset counter
if (otp != lastOTP) {
lastOTP = otp ;
otpCounter = 1;
} else
otpCounter++ ;
// ready to prepare
// otp + left padded i
var id = otp + (""+otpCounter).PadLeft(5, '0') ;
// make uri
var uri = new StringBuilder(repository.uriTemplate);
int j = 0;
for (int ii = 0; ii < uri.Length; ii++) {
if (j >= id.Length)
uri[ii] = (char) ('0' + getrandom.Next(0,9));
else
if (uri[ii] == '#')
{
uri[ii] = id[j];
j++;
}
}
// thats it
return uri.ToString();
}
}
}