/// <summary> /// read the source field and fill the spread sheet in the field /// </summary> /// <param name="source"></param> /// <param name="newIsValid"></param> public Spreadsheet(TextReader source, Regex newIsValid) { isvalName = newIsValid; Regex oldIsvail = null; sheet = new Dictionary <string, cell>(); dependency = new DependencyGraph(); // Create an XmlSchemaSet object. XmlSchemaSet sc = new XmlSchemaSet(); // NOTE: To read states3.xsd this way, it must be stored in the same folder with the // executable. To arrange this, I set the "Copy to Output Directory" propery of states3.xsd to // "Copy If Newer", which will copy states3.xsd as part of each build (if it has changed // since the last build). sc.Add(null, "Spreadsheet.xsd"); // Configure validation. XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas = sc; settings.ValidationEventHandler += ValidationCallback; // try to read the field try { // begin to read using (XmlReader reader = XmlReader.Create(source, settings)) { // in the each token, // first check if it is vaild // then save them into the sheet once it is vaild while (reader.Read()) { if (reader.IsStartElement()) { switch (reader.Name) { case "spreadsheet": try { oldIsvail = new Regex(reader["IsValid"]); } catch { throw new SpreadsheetReadException("wrong regular expression"); } break; // checkall the requirements case "cell": try { string name = reader["name"]; if (!oldIsvail.IsMatch(name)) { throw new SpreadsheetReadException("the name is ilegal"); } if (!isvalName.IsMatch(name)) { throw new SpreadsheetVersionException("the name is ilegal"); } if (sheet.ContainsKey(name)) { throw new SpreadsheetReadException("the name is duplicate"); } SetContentsOfCell(name, reader["contents"]); } catch { throw new SpreadsheetReadException("can not read name or contents"); } break; } } } } } // throw exception once it doen't read catch { throw new IOException(); } }
/// <summary> /// the spreadsheet will takes no peremeter /// </summary> public Spreadsheet() { sheet = new Dictionary <string, cell>(); dependency = new DependencyGraph(); constructorUse = 1; }
/// <summary> /// it will take a new isVaild check if match the requirement /// </summary> /// <param name="isValid"></param> public Spreadsheet(Regex isValid) { isvalName = isValid; sheet = new Dictionary <string, cell>(); dependency = new DependencyGraph(); }
/// Creates a Spreadsheet that is a duplicate of the spreadsheet saved in source. public Spreadsheet(TextReader source, Regex newIsValid) { this.dg = new DependencyGraph(); this.cellList = new Dictionary <string, Cell>(); IsValid = newIsValid; this.Changed = false; Regex r = newIsValid; XmlSchemaSet schema = new XmlSchemaSet(); schema.Add(null, "Spreadsheet.xsd"); XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas = schema; settings.ValidationEventHandler += ThrowExceptionValidation; using (XmlReader reader = XmlReader.Create(source, settings)) { while (reader.Read()) { if (reader.IsStartElement()) { switch (reader.Name) { case "spreadsheet": try { r = new Regex(reader["IsValid"]); } catch { throw new SpreadsheetReadException("Invalid Expression"); } break; case "cell": if (cellList.ContainsKey(reader["name"])) { throw new SpreadsheetReadException(""); } IsValid = r; try { this.SetContentsOfCell(reader["name"], reader["contents"]); } catch (Exception e) when(e is FormulaFormatException || e is CircularException || e is InvalidNameException) { if (e is FormulaFormatException) { throw new SpreadsheetVersionException(""); } if (e is FormulaFormatException) { throw new SpreadsheetVersionException(""); } if (e is InvalidNameException) { throw new SpreadsheetVersionException(""); } } IsValid = newIsValid; try { this.SetContentsOfCell(reader["name"], reader["contents"]); } catch (Exception ee) when(ee is FormulaFormatException || ee is CircularException || ee is InvalidNameException) { if (ee is FormulaFormatException) { throw new SpreadsheetVersionException(""); } if (ee is FormulaFormatException) { throw new SpreadsheetVersionException(""); } if (ee is InvalidNameException) { throw new SpreadsheetVersionException(""); } } break; } } } } }
/// <summary> /// Three argument constructor. /// </summary> /// <param name="isValid"></param> /// <param name="normalize"></param> /// <param name="version"></param> public Spreadsheet(Func <string, bool> isValid, Func <string, string> normalize, string version) : base(isValid, normalize, version) { dg = new DependencyGraph(); sd = new Dictionary <string, Cell>(); Changed = false; }
/// <summary> /// Constructs an abstract spreadsheet by recording its variable validity test, /// its normalization method, and its version information. The variable validity /// test is used throughout to determine whether a string that consists of one or /// more letters followed by one or more digits is a valid cell name. The variable /// equality test should be used thoughout to determine whether two variables are /// equal. /// </summary> public Spreadsheet(string filePath, Func <string, bool> isValid, Func <string, string> normalize, string version) : base(isValid, normalize, version) { //read save file from filePath spreadsheet = new Dictionary <string, Cell> { }; dependency_graph = new DependencyGraph(); has_changed = false; try { using (XmlReader read_file = XmlReader.Create(filePath)) { if (GetSavedVersion(filePath) != version) { throw new SpreadsheetReadWriteException("File versions are not the same."); } try { string cell_name = ""; while (read_file.Read()) { if (read_file.IsStartElement()) { switch (read_file.Name) { case "spreadsheet": break; case "cell": break; case "name": read_file.Read(); cell_name = read_file.Value; break; case "contents": read_file.Read(); try { SetContentsOfCell(cell_name, read_file.Value); } catch (Exception ex) { throw new SpreadsheetReadWriteException(ex.Message); } break; } } } } catch { throw new SpreadsheetReadWriteException("Error while reading from file"); } } } catch (Exception ex) { throw new SpreadsheetReadWriteException(ex.Message); } has_changed = false; }
/// <summary> /// zero-argument constructor should create an empty spreadsheet that imposes no /// extra validity conditions, normalizes every cell name to itself, /// and has version "default". /// </summary> public Spreadsheet() : base(s => true, s => s, "default") { Changed = false; myDG = new DependencyGraph(); mySS = new Dictionary <string, Cell>(); }
/// <summary> /// A zero-argument constructor that creates an empty spreadsheet. /// </summary> public Spreadsheet() { Graph = new DependencyGraph(); NonEmptyCells = new Dictionary <string, Cell>(); }
/// <summary> /// No arguments in constructor. Cell validity has same rule for all /// spreadsheets, and is determined by IsValid method in this class. /// Cell name normalization has same rule (all uppercase letters) for all /// spreadsheets, and is determined by Normalize method in this class. /// </summary> public Spreadsheet() { cells = new Dictionary <string, Cell>(); dependencyGraph = new DependencyGraph(); }
public Spreadsheet(string path, Func <string, bool> isValid, Func <string, string> normalize, string version) : base(x => true, x => x, version) { //declaring a dependency graph. DG = new DependencyGraph(); //declarign a cell from the cells class. Cells = new Dictionary <string, Cell>(); //declaring is Valid and Normalize this.IsValid = isValid; this.Normalize = normalize; this.Version = version; Changed = false; try { //reading a file from the path using (XmlReader reader = XmlReader.Create(path)) { while (reader.Read()) { //if start element is correct. if (reader.IsStartElement()) { //if spreadsheet is read. if (reader.Name == "spreadsheet") { //set version to reader version. version = reader["version"]; } //if cell is read. if (reader.Name == "cell") { //if reader Name is not equal to name. while (!reader.Name.Equals("name")) { reader.Read(); } reader.Read(); //storing value in name. string name = reader.Value; while (!reader.Name.Equals("contents")) { reader.Read(); } reader.Read(); //set value in content. string content = reader.Value; //rerunning setCentent of cell on name and content. SetContentsOfCell(name, content); } } } } } catch (Exception) { throw new SpreadsheetReadWriteException("error"); } //if version doesnt match throw an exception. if (!GetSavedVersion(path).Equals(Version)) { throw new SpreadsheetReadWriteException("the version do not match"); } }
/// <summary> /// Requires that all of the variables in formula are valid cell names. /// /// If name is null or invalid, throws an InvalidNameException. /// /// Otherwise, if changing the contents of the named cell to be the formula would cause a /// circular dependency, throws a CircularException. /// /// Otherwise, the contents of the named cell becomes formula. The method returns a /// Set consisting of name plus the names of all other cells whose value depends, /// directly or indirectly, on the named cell. /// /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the /// set {A1, B1, C1} is returned. /// </summary> protected override ISet <string> SetCellContents(string name, Formula formula) { name = name.ToUpper(); // check if passed in formula contains a dependent of the named cell // to prevent a ciruclar dependency //foreach(string token in GetDirectDependents(name)) //{ // if(formula.ToString().Contains(token)) // { // throw new CircularException(); // } //} HashSet <string> set = new HashSet <string>(); // A backup spreadsheet for revert in case a CircularException is thrown Dictionary <string, Cell> tempDict = new Dictionary <string, Cell>(); // A backup DependencyGraph for revert in case a CircularException is thrown DependencyGraph tempGraph = new DependencyGraph(graph); //create a copy for the spreadsheet foreach (KeyValuePair <string, Cell> key in cellList) { tempDict.Add(key.Key, key.Value); } // Replace current cell's content for update graph.ReplaceDependees(name, new List <string>()); // Create dependency relationship between cell and valid variables generated by Formula foreach (string var in formula.GetVariables()) { CheckParameters(var); graph.AddDependency(var, name); } // Generate a new cell if such named cell doesn't exists yet, or simply replace the existing // cell with new information GenerateCellInfo(name, formula); set.Add(name); // This try catch block is used to detect possible Circular dependency by calling GetCellsToRecalculate() try { foreach (string var in GetCellsToRecalculate(name)) { set.Add(var); } } catch (CircularException e) { // If a CircularException is caught, revert the entire operation. cellList = tempDict; graph = tempGraph; Changed = false; throw e; } // Update current named cell's dependee's content, value and dependency UpdateCellInfo(set, name); Changed = true; return(set); }
/// Creates a Spreadsheet that is a duplicate of the spreadsheet saved in source. /// /// See the AbstractSpreadsheet.Save method and Spreadsheet.xsd for the file format /// specification. /// /// If there's a problem reading source, throws an IOException. /// /// Else if the contents of source are not consistent with the schema in Spreadsheet.xsd, /// throws a SpreadsheetReadException. /// /// Else if the IsValid string contained in source is not a valid C# regular expression, throws /// a SpreadsheetReadException. (If the exception is not thrown, this regex is referred to /// below as oldIsValid.) /// /// Else if there is a duplicate cell name in the source, throws a SpreadsheetReadException. /// (Two cell names are duplicates if they are identical after being converted to upper case.) /// /// Else if there is an invalid cell name or an invalid formula in the source, throws a /// SpreadsheetReadException. (Use oldIsValid in place of IsValid in the definition of /// cell name validity.) /// /// Else if there is an invalid cell name or an invalid formula in the source, throws a /// SpreadsheetVersionException. (Use newIsValid in place of IsValid in the definition of /// cell name validity.) /// /// Else if there's a formula that causes a circular dependency, throws a SpreadsheetReadException. /// /// Else, create a Spreadsheet that is a duplicate of the one encoded in source except that /// the new Spreadsheet's IsValid regular expression should be newIsValid. public Spreadsheet(TextReader source, Regex newIsValid) { cells = new Dictionary <string, Cell>(); dependencies = new DependencyGraph(); validator = newIsValid; XmlSchemaSet sc = new XmlSchemaSet(); sc.Add(null, "Spreadsheet.xsd"); XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas = sc; settings.ValidationEventHandler += delegate(object sender, ValidationEventArgs e) { throw new SpreadsheetReadException("Validation Error: " + e); }; Regex oldIsValid = new Regex(""); using (XmlReader reader = XmlReader.Create(source, settings)) { while (reader.Read()) { if (reader.IsStartElement()) { switch (reader.Name) { case "spreadsheet": try { oldIsValid = new Regex(reader["IsValid"]); } catch (Exception e) { throw new SpreadsheetReadException(e.Message); } break; case "cell": if (cells.ContainsKey(reader["name"].ToUpper())) { throw new SpreadsheetReadException("Duplicate cell name: " + reader["name"].ToUpper()); } if (!oldIsValid.IsMatch(reader["name"])) { throw new SpreadsheetReadException("According to the old IsValid regex, " + reader["name"] + " is not a valid cell name"); } if (!validator.IsMatch(reader["name"])) { throw new SpreadsheetVersionException("According to the new IsValid regex, " + reader["name"] + " is not a valid cell name"); } ValidateVarsUsingOld(reader["contents"], oldIsValid); try { SetContentsOfCell(reader["name"], reader["contents"]); } catch (CircularException e) { throw new SpreadsheetReadException(e.Message); } catch (Exception e) { throw new SpreadsheetVersionException(e.Message); } break; } } } } changed = false; }
/// <summary> /// Constructor for Spreadsheet to create a new spreadsheetCells dictionary /// and a dependencies dependency graph object. /// This constructor creates a Spreadsheet that is a duplicate of the spreadsheet /// saved in source. /// If there's a problem reading source, throws an IOException /// If the contents of source is not formatted properly, throws a SpreadsheetReadException. /// </summary> public Spreadsheet(TextReader source) { try { // Create an empty spreadsheetCells dictionary spreadsheetCells = new Dictionary <String, Cell>(); // Create an empty dependencies DG dependencies = new DependencyGraph(); // Read in the XML file using (XmlReader reader = XmlReader.Create(source)) { // Create a temporary cell object Cell readCell = new Cell(); while (reader.Read()) { if (reader.IsStartElement()) { switch (reader.Name) { // If reader is on spreadsheet, read in and set the isvalid regex case "spreadsheet": reader.MoveToFirstAttribute(); reader.ReadAttributeValue(); String regex = reader.Value; Regex tempRegex = new Regex(regex); isValidRegex = tempRegex; break; // If reader is on cell, initialize a new temporary cell case "cell": readCell = new Cell(); break; // If reader is on name, set the temporary cell's name to name case "name": reader.Read(); String name = reader.Value; readCell.cellName = name; break; // If reader is on contents, set the temporary cell's contents to contents // and add the temporary cell to the spreadsheet case "contents": reader.Read(); String contents = reader.Value; readCell.cellContents = contents; SetContentsOfCell(readCell.cellName, contents); break; } } } } // Set Changed equal to false Changed = false; } catch (IOException) { throw new IOException(); } catch (XmlException e) { throw new SpreadsheetReadException(e.Message); } }
/// <summary> /// Constructor for Spreadsheet with zero arguments /// </summary> public Spreadsheet() { dependency_graph = new DependencyGraph(); cell = new Dictionary <String, Cell>(); }
/// <summary> /// Creates a Spreadsheet that is a duplicate of the spreadsheet saved in source. /// See the AbstractSpreadsheet.Save method for the file format specification. /// If there's a problem reading source, throws an IOException /// If the contents of source is not formatted properly, throws a SpreadsheetReadException /// /// Sample reading file: /// /// <spreadsheet isvalid="IsValid regex goes here"> /// <cell> /// <name> /// cell name goes here /// </name> /// <contents> /// cell contents goes here /// </contents> /// </cell> /// </spreadsheet> /// /// The value of the isvalid attribute should be IsValid.ToString() /// </summary> public Spreadsheet(TextReader source) { // Initiating our DependencyGraph and our Cells Dictionary DGSpreadsheet = new DependencyGraph(); cellDictionary = new Dictionary <string, Cell>(); // Local variables to hold the xml data (name of cell and content of cell) string tempCellName = ""; string tempContent = ""; isValidBool = true; // Using xml processing to break the different elements of a source reader into // usuable information to make a spreadsheet. If we have difficulty reading the input file // we throw a IOException try { using (XmlReader xmlReader = XmlReader.Create(source)) { // if any elements read are not in an appropriate format, // we throw a Spreadsheet read exception try { while (xmlReader.Read()) { if (xmlReader.IsStartElement()) { switch (xmlReader.Name.ToString()) { // Checking for the title of the xml file and grabbing // a regex expression if one exists case "spreadsheet": isValid = new Regex(xmlReader.GetAttribute("isvalid")); break; // cell is checked only for formatting purposes that were given // in the assignment description case "cell": break; // Grabing the name of the cell (stored in a temp variable) case "name": tempCellName = xmlReader.ReadString(); // Checking if the name is valid if (!nameValidation(tempCellName)) { throw new InvalidNameException(); } break; // Grabing the content of the cell and setting a cell using SetContentsOfCell case "contents": tempContent = xmlReader.ReadString(); SetContentsOfCell(tempCellName, tempContent); break; default: throw new SpreadsheetReadException("Error in reading spreadsheet"); } } } Changed = false; } catch (Exception) { throw new SpreadsheetReadException("There was a problem reading from the input file."); } } } catch (IOException) { throw new IOException("There was an issue reading from the source file"); } }
/// <summary> /// constructor for spreadsheet with no parameters /// /// </summary> public Spreadsheet() : base(s => true, s => s, "default") { spreadsheet = new Dictionary <string, Cell>(); graph = new DependencyGraph(); changed = false; }
/// <summary> /// creates a Spreadsheet from a saved file /// </summary> public Spreadsheet(TextReader source, Regex newIsValid)//CHANGE HERE FOR REGRADE { cells = new Dictionary <string, Cell>(); dg = new DependencyGraph(); changed = false; try { XmlSchemaSet sc = new XmlSchemaSet(); sc.Add(null, "Spreadsheet.xsd"); XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas = sc; //using xml reader to read file try { XmlReader reader = XmlReader.Create(source, settings);//CHANGE HERE //cell name string cellName = ""; //cell value string cellContent = ""; bool RegexMatch = true; bool setContents; while (reader.Read()) { if (reader.IsStartElement()) { setContents = false; string name = reader.Name; switch (name) { case "spreadsheet": string v = reader.GetAttribute("IsValid"); try { oldValid = new Regex(v); } catch (Exception) { throw new SpreadsheetReadException("invalid Regex"); } if (string.IsNullOrEmpty(oldValid.ToString())) { RegexMatch = false; } else if (oldValid.ToString().Equals(newIsValid.ToString())) { RegexMatch = true; } valid = newIsValid; break; //read the cell name case "cell": string a = reader.GetAttribute("name"); cellName = a; string b = reader.GetAttribute("contents"); cellContent = b; setContents = true; if (!Regex.IsMatch(a, newIsValid.ToString())) { throw new SpreadsheetVersionException("Spreadsheet version"); } if (!Regex.IsMatch(a, oldValid.ToString())) { throw new SpreadsheetReadException("invalid regex"); } break; } if (!RegexMatch) { throw new SpreadsheetReadException("Regex does not match"); } if (setContents) { if (cells.ContainsKey(cellName)) { throw new SpreadsheetReadException("duplicate cell"); } SetContentsOfCell(cellName, cellContent); } } } reader.Close(); } catch (XmlException) { throw new SpreadsheetReadException("Spreadsheet cannot be read"); } } catch (XmlSchemaException) { throw new SpreadsheetReadException("Spreadsheet cannot be read"); } }
/// <summary> /// Empty argument constructor. /// </summary> public Spreadsheet() : base(s => true, s => s, "default") { graph = new DependencyGraph(); cellMap = new Dictionary <string, Cell>(); }
/// If there's a problem reading source, throws an IOException. /// /// Else if the contents of source are not consistent with the schema in Spreadsheet.xsd, /// throws a SpreadsheetReadException. /// /// Else if the IsValid string contained in source is not a valid C# regular expression, throws /// a SpreadsheetReadException. (If the exception is not thrown, this regex is referred to /// below as oldIsValid.) /// /// Else if there is a duplicate cell name in the source, throws a SpreadsheetReadException. /// (Two cell names are duplicates if they are identical after being converted to upper case.) /// /// Else if there is an invalid cell name or an invalid formula in the source, throws a /// SpreadsheetReadException. (Use oldIsValid in place of IsValid in the definition of /// cell name validity.) /// /// Else if there is an invalid cell name or an invalid formula in the source, throws a /// SpreadsheetVersionException. (Use newIsValid in place of IsValid in the definition of /// cell name validity.) /// /// Else if there's a formula that causes a circular dependency, throws a SpreadsheetReadException. /// /// Else, create a Spreadsheet that is a duplicate of the one encoded in source except that /// the new Spreadsheet's IsValid regular expression should be newIsValid. public Spreadsheet(TextReader source, Regex newIsValid) { this.dg = new DependencyGraph(); this.cells = new Dictionary <string, Cell>(); Regex checkValid = newIsValid; XmlSchemaSet schema = new XmlSchemaSet(); schema.Add(null, "Spreadsheet.xsd"); XmlReaderSettings xmlSetting = new XmlReaderSettings(); xmlSetting.ValidationType = ValidationType.Schema; xmlSetting.Schemas = schema; xmlSetting.ValidationEventHandler += (object sender, ValidationEventArgs e) => throw new SpreadsheetReadException("not valid"); using (XmlReader xmlReader = XmlReader.Create(source, xmlSetting)) { while (xmlReader.Read()) { if (xmlReader.IsStartElement()) { if (xmlReader.Name == "cell") { if (cells.ContainsKey(xmlReader["name"])) { throw new SpreadsheetReadException("duplicate cell in the source"); } IsValid = checkValid; try { this.SetContentsOfCell(xmlReader["name"], xmlReader["contents"]); } catch (FormulaFormatException e) { throw new SpreadsheetReadException("invalid"); } catch (CircularException e) { throw new SpreadsheetReadException("invalid"); } catch (InvalidNameException e) { throw new SpreadsheetReadException("invalid"); } IsValid = newIsValid; try { this.SetContentsOfCell(xmlReader["name"], xmlReader["contents"]); } catch (FormulaFormatException e) { throw new SpreadsheetVersionException("invalid"); } catch (CircularException e) { throw new SpreadsheetVersionException("invalid"); } catch (InvalidNameException e) { throw new SpreadsheetVersionException("invalid"); } } else if (xmlReader.Name == "spreadsheet") { try { checkValid = new Regex(xmlReader["IsValid"]); } catch (ArgumentException e) { throw new SpreadsheetReadException("invalid"); } } } } } }
// ADDED FOR PS5 /// <summary> /// Constructs a spreadsheet by recording its variable validity test, /// its normalization method, and its version information. The variable validity /// test is used throughout to determine whether a string that consists of one or /// more letters followed by one or more digits is a valid cell name. The variable /// equality test should be used thoughout to determine whether two variables are /// equal. /// </summary> public Spreadsheet(Func <string, bool> isValid, Func <string, string> normalize, string version) : base(isValid, normalize, version) { usedCells = new Dictionary <string, Cell>(); depGraph = new DependencyGraph(); }
/// <summary> /// constrctor /// </summary> public Spreadsheet() { DG = new DependencyGraph(); Sheet = new Dictionary <string, Cell>(); }
/// <summary> /// Constructor Method, sets all data values to new. /// </summary> public Spreadsheet() : base(s => true, s => s, "default") { spreadSheetCells = new Dictionary <string, Cell>(); dependencies = new DependencyGraph(); Changed = false; }