Exemplo n.º 1
0
        public ActionResult Create(Marker marker)
        {
            if (ModelState.IsValid) {
                int userId = WebSecurity.GetUserId(User.Identity.Name);

                using (TransactionScope trans = new TransactionScope()) {
                    try {
                        var markerText = marker.Text.Trim();

                        bool isStart = false;
                        bool isStop = false;

                        bool setStartTime = false;
                        bool setDuration = false;
                        bool isDuration = false;

                        int? durationDays = null;
                        int? durationHours = null;
                        int? durationMinutes = null;
                        int? startTimeHours = null;
                        int? startTimeMinutes = null;

                        bool canCommit = true;

                        // Store the Marker.
                        var newMarker = new Marker();
                        newMarker.CreatedByUserId = userId;
                        newMarker.CreatedUtc = DateTime.UtcNow;
                        newMarker.Text = markerText;

                        db.Markers.Add(newMarker);
                        db.SaveChanges();

                        // Process the commands part first...
                        // Is this a start or end?
                        if (markerText.EndsWith("+")) {
                            isStart = true;
                            markerText = markerText.TrimEnd('+').Trim();
                        } else if (markerText.EndsWith("-")) {
                            isStop = true;
                            markerText = markerText.TrimEnd('-').Trim();
                        }

                        var durationMatch = Regex.Match(markerText, "-[dD]:[0-9]{2,6}");

                        if (durationMatch.Success) {
                            setDuration = true;

                            // We have been given a duration indicator
                            // so we'll create a completed marker instance with
                            // Start/End equal to duration

                            //2 chars == minutes
                            //4 chars == hours.minutes
                            //6 chars == days.hours.minutes
                        }

                        var timeMatch = Regex.Match(markerText, @"-[tT]:[0-2]{1}[0-9]{1}[0-5]{1}[0-9]{1}");

                        if (timeMatch.Success) {
                            setStartTime = true;

                            startTimeHours = System.Convert.ToInt32(timeMatch.Value.Substring(3, 2));
                            startTimeMinutes = System.Convert.ToInt32(timeMatch.Value.Substring(5, 2));
                        }

                        // TODO Duration and Time commands

                        // Keyword processing...
                        // Parse the sections, keywords and the rest...

                        //if (markerText.Contains(";")) {
                        var markerParts = markerText
                            .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                        // What if they haven't specified a ; char?
                        // Do we consider it to be all Keywords
                        // Or do we require a ;
                        // Easier to require it than provide the functionality to clean up afterwards
                        // if they are entering using a UI then we can ensure the proper structure
                        // If they are entering via text then they should know better.

                        // Alternatively, we could have a generic TEMP keyword that stuff could be assigned
                        // to in the absense of a specific Keyword

                        var keywordsText = markerParts[0].TrimStart().Trim();
                        string messageText = null;

                        if (markerParts.Length > 1) {
                            messageText = markerParts[1].TrimStart().Trim();
                        }

                        var keywordParts = keywordsText
                            .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                            .ToList();

                        int? parentId = null;
                        var keywordInstances = new List<KeywordInstance>();

                        for (int i = 0; i < keywordParts.Count(); i++) {
                            bool bottomOfTheStack = (i == keywordParts.Count() - 1);

                            var currentKeywordText = keywordParts[i].TrimStart().Trim();

                            // Does this keyword already exist for this user?
                            var currentKeyword = db.Keywords
                                .SingleOrDefault(kw => kw.Text.ToLower() == currentKeywordText.ToLower() &&
                                    kw.CreatedByUserId == userId);

                            if (currentKeyword == null) {
                                currentKeyword = new Keyword();
                                currentKeyword.CreatedByUserId = userId;
                                currentKeyword.Text = currentKeywordText;
                                currentKeyword.CreatedUtc = DateTime.UtcNow;

                                db.Keywords.Add(currentKeyword);
                                db.SaveChanges();
                            }

                            // Is this keyword already in use?
                            // ie. Is there already a Keyword Instance in use?
                            var currentKeywordInstance = db.KeywordInstances
                                .SingleOrDefault(kwi => kwi.KeywordId == currentKeyword.KeywordId &&
                                    ((parentId == null && kwi.ParentInstanceId == null) ||
                                    (kwi.ParentInstanceId == parentId)));

                            if (currentKeywordInstance == null) {
                                currentKeywordInstance = new KeywordInstance();
                                currentKeywordInstance.KeywordId = currentKeyword.KeywordId;
                                currentKeywordInstance.CreatedUtc = DateTime.UtcNow;

                                // if we have been told to start then all instances need to be running...
                                currentKeywordInstance.IsRunning = isStart;
                                currentKeywordInstance.ParentInstanceId = parentId;

                                // Are we a parent?
                                // If we are not at the bottom of the stack then yes we are.
                                if (!bottomOfTheStack) {
                                    currentKeywordInstance.IsParent = true;
                                }

                                currentKeyword.KeywordInstances.Add(currentKeywordInstance);
                            } else {
                                if (isStart) {
                                    // TODO NB. Check that we're not already running.
                                    // We need to check this at the bottom of the stack
                                    // If it's already running then we don't want to reissue the
                                    // command.

                                    // Might need to do this on the way back up for parent instances.

                                    currentKeywordInstance.IsRunning = true;
                                }

                                // Are we a parent?
                                // If we are not at the bottom of the stack then yes we are.
                                if (!bottomOfTheStack) {
                                    currentKeywordInstance.IsParent = true;
                                }

                                // Are we stopping?
                                // We will do this as a second pass to make sure we stop correctly.
                            }

                            // NB. If they do not specify the parentage of the keyword they
                            // will end up with a separate instance of the keyword which
                            // they can hook up later.

                            // Are we to create an instance action?
                            // For parents we are only concerned with Starts (if we are not already started)
                            // For the instance at the bottom of the pile we will be concerned
                            // with all.
                            bool createInstanceAction = false;
                            InstanceActionType instanceActionType = null;

                            // Are we in the last keyword?
                            if (bottomOfTheStack) {
                                // Create a new Instance Action
                                // else, note the id of this instance as the parent of the next.
                                var newAction = new InstanceAction();

                                if (isStart) {
                                    instanceActionType = db.InstanceActionTypes
                                        .Single(ia => ia.TypeName == "Start");
                                    createInstanceAction = true;
                                } else if (!isStop) {
                                    instanceActionType = db.InstanceActionTypes
                                        .Single(ia => ia.TypeName == "Note");
                                    createInstanceAction = true;
                                }
                            } else {
                                if (isStart) {
                                    instanceActionType = db.InstanceActionTypes
                                        .Single(ia => ia.TypeName == "ChildStart");
                                    createInstanceAction = true;

                                    // TODO Might need to do this on the way back up
                                    // after we've checked that this command is necessary
                                    // NB. Stops will be dealt with on the way back.
                                }
                            }

                            if (createInstanceAction) {
                                // Create a new Instance Action
                                // else, note the id of this instance as the parent of the next.
                                var newAction = new InstanceAction();

                                newAction.InstanceActionType = instanceActionType;
                                newAction.Text = messageText;
                                newAction.CreatedUtc = DateTime.UtcNow;
                                newAction.MarkerId = newMarker.MarkerId;

                                currentKeywordInstance.Actions.Add(newAction);
                            }

                            db.SaveChanges();

                            keywordInstances.Add(currentKeywordInstance);
                            parentId = currentKeywordInstance.KeywordInstanceId;
                        }

                        // If we have been asked to stop then we have to back up
                        // the hierarchy to check which ca be stopped.
                        // If a parent instance still has running instances then we cannot stop
                        // that parent.

                        if (isStop) {
                            StopKeywordInstance(keywordInstances.Last().KeywordInstanceId, false);
                        }
                        //} else {
                        // Send it back
                        // "Keywords not correctly specified.".Dump();
                        //}

                        if (canCommit) {
                            trans.Complete();
                        }

                        // TODO ELSE let them know why such as duplicate start

                        return RedirectToAction("Index", "Home");
                    } catch (Exception ex) {
                        // Deal with it
                        // Return a message saying that something has gone wrong
                        throw new Exception("Could not complete action: " + ex.Message);
                    }
                }
            }

            return View(marker);
        }
Exemplo n.º 2
0
 public ActionResult Edit(Marker marker)
 {
     if (ModelState.IsValid) {
         db.Entry(marker).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("Index");
     }
     return View(marker);
 }