23 skills found
santimattius / Kmp ResilientA Kotlin Multiplatform library providing resilience patterns (Timeout, Retry, Circuit Breaker, Rate Limiter, Bulkhead, Hedging, Cache, Fallback) for suspend functions. Compose them declaratively with a small DSL and observe runtime telemetry via Flow.
kenchris / JakecacheDeclarative manifest-driven app cache top of ServiceWorker
noahgrant / ResourcererDeclarative data-fetching and caching framework for REST APIs with React
rramatchandran / Big O Performance Java# big-o-performance A simple html app to demonstrate performance costs of data structures. - Clone the project - Navigate to the root of the project in a termina or command prompt - Run 'npm install' - Run 'npm start' - Go to the URL specified in the terminal or command prompt to try out the app. # This app was created from the Create React App NPM. Below are instructions from that project. Below you will find some information on how to perform common tasks. You can find the most recent version of this guide [here](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md). ## Table of Contents - [Updating to New Releases](#updating-to-new-releases) - [Sending Feedback](#sending-feedback) - [Folder Structure](#folder-structure) - [Available Scripts](#available-scripts) - [npm start](#npm-start) - [npm run build](#npm-run-build) - [npm run eject](#npm-run-eject) - [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor) - [Installing a Dependency](#installing-a-dependency) - [Importing a Component](#importing-a-component) - [Adding a Stylesheet](#adding-a-stylesheet) - [Post-Processing CSS](#post-processing-css) - [Adding Images and Fonts](#adding-images-and-fonts) - [Adding Bootstrap](#adding-bootstrap) - [Adding Flow](#adding-flow) - [Adding Custom Environment Variables](#adding-custom-environment-variables) - [Integrating with a Node Backend](#integrating-with-a-node-backend) - [Proxying API Requests in Development](#proxying-api-requests-in-development) - [Deployment](#deployment) - [Now](#now) - [Heroku](#heroku) - [Surge](#surge) - [GitHub Pages](#github-pages) - [Something Missing?](#something-missing) ## Updating to New Releases Create React App is divided into two packages: * `create-react-app` is a global command-line utility that you use to create new projects. * `react-scripts` is a development dependency in the generated projects (including this one). You almost never need to update `create-react-app` itself: it’s delegates all the setup to `react-scripts`. When you run `create-react-app`, it always creates the project with the latest version of `react-scripts` so you’ll get all the new features and improvements in newly created apps automatically. To update an existing project to a new version of `react-scripts`, [open the changelog](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md), find the version you’re currently on (check `package.json` in this folder if you’re not sure), and apply the migration instructions for the newer versions. In most cases bumping the `react-scripts` version in `package.json` and running `npm install` in this folder should be enough, but it’s good to consult the [changelog](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md) for potential breaking changes. We commit to keeping the breaking changes minimal so you can upgrade `react-scripts` painlessly. ## Sending Feedback We are always open to [your feedback](https://github.com/facebookincubator/create-react-app/issues). ## Folder Structure After creation, your project should look like this: ``` my-app/ README.md index.html favicon.ico node_modules/ package.json src/ App.css App.js index.css index.js logo.svg ``` For the project to build, **these files must exist with exact filenames**: * `index.html` is the page template; * `favicon.ico` is the icon you see in the browser tab; * `src/index.js` is the JavaScript entry point. You can delete or rename the other files. You may create subdirectories inside `src`. For faster rebuilds, only files inside `src` are processed by Webpack. You need to **put any JS and CSS files inside `src`**, or Webpack won’t see them. You can, however, create more top-level directories. They will not be included in the production build so you can use them for things like documentation. ## Available Scripts In the project directory, you can run: ### `npm start` Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.<br> You will also see any lint errors in the console. ### `npm run build` Builds the app for production to the `build` folder.<br> It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed! ### `npm run eject` **Note: this is a one-way operation. Once you `eject`, you can’t go back!** If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. ## Displaying Lint Output in the Editor >Note: this feature is available with `react-scripts@0.2.0` and higher. Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint. They are not required for linting. You should see the linter output right in your terminal as well as the browser console. However, if you prefer the lint results to appear right in your editor, there are some extra steps you can do. You would need to install an ESLint plugin for your editor first. >**A note for Atom `linter-eslint` users** >If you are using the Atom `linter-eslint` plugin, make sure that **Use global ESLint installation** option is checked: ><img src="http://i.imgur.com/yVNNHJM.png" width="300"> Then make sure `package.json` of your project ends with this block: ```js { // ... "eslintConfig": { "extends": "./node_modules/react-scripts/config/eslint.js" } } ``` Projects generated with `react-scripts@0.2.0` and higher should already have it. If you don’t need ESLint integration with your editor, you can safely delete those three lines from your `package.json`. Finally, you will need to install some packages *globally*: ```sh npm install -g eslint babel-eslint eslint-plugin-react eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-flowtype ``` We recognize that this is suboptimal, but it is currently required due to the way we hide the ESLint dependency. The ESLint team is already [working on a solution to this](https://github.com/eslint/eslint/issues/3458) so this may become unnecessary in a couple of months. ## Installing a Dependency The generated project includes React and ReactDOM as dependencies. It also includes a set of scripts used by Create React App as a development dependency. You may install other dependencies (for example, React Router) with `npm`: ``` npm install --save <library-name> ``` ## Importing a Component This project setup supports ES6 modules thanks to Babel. While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead. For example: ### `Button.js` ```js import React, { Component } from 'react'; class Button extends Component { render() { // ... } } export default Button; // Don’t forget to use export default! ``` ### `DangerButton.js` ```js import React, { Component } from 'react'; import Button from './Button'; // Import a component from another file class DangerButton extends Component { render() { return <Button color="red" />; } } export default DangerButton; ``` Be aware of the [difference between default and named exports](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281). It is a common source of mistakes. We suggest that you stick to using default imports and exports when a module only exports a single thing (for example, a component). That’s what you get when you use `export default Button` and `import Button from './Button'`. Named exports are useful for utility modules that export several functions. A module may have at most one default export and as many named exports as you like. Learn more about ES6 modules: * [When to use the curly braces?](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281) * [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html) * [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules) ## Adding a Stylesheet This project setup uses [Webpack](https://webpack.github.io/) for handling all assets. Webpack offers a custom way of “extending” the concept of `import` beyond JavaScript. To express that a JavaScript file depends on a CSS file, you need to **import the CSS from the JavaScript file**: ### `Button.css` ```css .Button { padding: 20px; } ``` ### `Button.js` ```js import React, { Component } from 'react'; import './Button.css'; // Tell Webpack that Button.js uses these styles class Button extends Component { render() { // You can use them as regular CSS styles return <div className="Button" />; } } ``` **This is not required for React** but many people find this feature convenient. You can read about the benefits of this approach [here](https://medium.com/seek-ui-engineering/block-element-modifying-your-javascript-components-d7f99fcab52b). However you should be aware that this makes your code less portable to other build tools and environments than Webpack. In development, expressing dependencies this way allows your styles to be reloaded on the fly as you edit them. In production, all CSS files will be concatenated into a single minified `.css` file in the build output. If you are concerned about using Webpack-specific semantics, you can put all your CSS right into `src/index.css`. It would still be imported from `src/index.js`, but you could always remove that import if you later migrate to a different build tool. ## Post-Processing CSS This project setup minifies your CSS and adds vendor prefixes to it automatically through [Autoprefixer](https://github.com/postcss/autoprefixer) so you don’t need to worry about it. For example, this: ```css .App { display: flex; flex-direction: row; align-items: center; } ``` becomes this: ```css .App { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } ``` There is currently no support for preprocessors such as Less, or for sharing variables across CSS files. ## Adding Images and Fonts With Webpack, using static assets like images and fonts works similarly to CSS. You can **`import` an image right in a JavaScript module**. This tells Webpack to include that image in the bundle. Unlike CSS imports, importing an image or a font gives you a string value. This value is the final image path you can reference in your code. Here is an example: ```js import React from 'react'; import logo from './logo.png'; // Tell Webpack this JS file uses this image console.log(logo); // /logo.84287d09.png function Header() { // Import result is the URL of your image return <img src={logo} alt="Logo" />; } export default function Header; ``` This works in CSS too: ```css .Logo { background-image: url(./logo.png); } ``` Webpack finds all relative module references in CSS (they start with `./`) and replaces them with the final paths from the compiled bundle. If you make a typo or accidentally delete an important file, you will see a compilation error, just like when you import a non-existent JavaScript module. The final filenames in the compiled bundle are generated by Webpack from content hashes. If the file content changes in the future, Webpack will give it a different name in production so you don’t need to worry about long-term caching of assets. Please be advised that this is also a custom feature of Webpack. **It is not required for React** but many people enjoy it (and React Native uses a similar mechanism for images). However it may not be portable to some other environments, such as Node.js and Browserify. If you prefer to reference static assets in a more traditional way outside the module system, please let us know [in this issue](https://github.com/facebookincubator/create-react-app/issues/28), and we will consider support for this. ## Adding Bootstrap You don’t have to use [React Bootstrap](https://react-bootstrap.github.io) together with React but it is a popular library for integrating Bootstrap with React apps. If you need it, you can integrate it with Create React App by following these steps: Install React Bootstrap and Bootstrap from NPM. React Bootstrap does not include Bootstrap CSS so this needs to be installed as well: ``` npm install react-bootstrap --save npm install bootstrap@3 --save ``` Import Bootstrap CSS and optionally Bootstrap theme CSS in the ```src/index.js``` file: ```js import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/css/bootstrap-theme.css'; ``` Import required React Bootstrap components within ```src/App.js``` file or your custom component files: ```js import { Navbar, Jumbotron, Button } from 'react-bootstrap'; ``` Now you are ready to use the imported React Bootstrap components within your component hierarchy defined in the render method. Here is an example [`App.js`](https://gist.githubusercontent.com/gaearon/85d8c067f6af1e56277c82d19fd4da7b/raw/6158dd991b67284e9fc8d70b9d973efe87659d72/App.js) redone using React Bootstrap. ## Adding Flow Flow typing is currently [not supported out of the box](https://github.com/facebookincubator/create-react-app/issues/72) with the default `.flowconfig` generated by Flow. If you run it, you might get errors like this: ```js node_modules/fbjs/lib/Deferred.js.flow:60 60: Promise.prototype.done.apply(this._promise, arguments); ^^^^ property `done`. Property not found in 495: declare class Promise<+R> { ^ Promise. See lib: /private/tmp/flow/flowlib_34952d31/core.js:495 node_modules/fbjs/lib/shallowEqual.js.flow:29 29: return x !== 0 || 1 / (x: $FlowIssue) === 1 / (y: $FlowIssue); ^^^^^^^^^^ identifier `$FlowIssue`. Could not resolve name src/App.js:3 3: import logo from './logo.svg'; ^^^^^^^^^^^^ ./logo.svg. Required module not found src/App.js:4 4: import './App.css'; ^^^^^^^^^^^ ./App.css. Required module not found src/index.js:5 5: import './index.css'; ^^^^^^^^^^^^^ ./index.css. Required module not found ``` To fix this, change your `.flowconfig` to look like this: ```ini [libs] ./node_modules/fbjs/flow/lib [options] esproposal.class_static_fields=enable esproposal.class_instance_fields=enable module.name_mapper='^\(.*\)\.css$' -> 'react-scripts/config/flow/css' module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|webp\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> 'react-scripts/config/flow/file' suppress_type=$FlowIssue suppress_type=$FlowFixMe ``` Re-run flow, and you shouldn’t get any extra issues. If you later `eject`, you’ll need to replace `react-scripts` references with the `<PROJECT_ROOT>` placeholder, for example: ```ini module.name_mapper='^\(.*\)\.css$' -> '<PROJECT_ROOT>/config/flow/css' module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|webp\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> '<PROJECT_ROOT>/config/flow/file' ``` We will consider integrating more tightly with Flow in the future so that you don’t have to do this. ## Adding Custom Environment Variables >Note: this feature is available with `react-scripts@0.2.3` and higher. Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have `NODE_ENV` defined for you, and any other environment variables starting with `REACT_APP_`. These environment variables will be defined for you on `process.env`. For example, having an environment variable named `REACT_APP_SECRET_CODE` will be exposed in your JS as `process.env.REACT_APP_SECRET_CODE`, in addition to `process.env.NODE_ENV`. These environment variables can be useful for displaying information conditionally based on where the project is deployed or consuming sensitive data that lives outside of version control. First, you need to have environment variables defined, which can vary between OSes. For example, let's say you wanted to consume a secret defined in the environment inside a `<form>`: ```jsx render() { return ( <div> <small>You are running this application in <b>{process.env.NODE_ENV}</b> mode.</small> <form> <input type="hidden" defaultValue={process.env.REACT_APP_SECRET_CODE} /> </form> </div> ); } ``` The above form is looking for a variable called `REACT_APP_SECRET_CODE` from the environment. In order to consume this value, we need to have it defined in the environment: ### Windows (cmd.exe) ```cmd set REACT_APP_SECRET_CODE=abcdef&&npm start ``` (Note: the lack of whitespace is intentional.) ### Linux, OS X (Bash) ```bash REACT_APP_SECRET_CODE=abcdef npm start ``` > Note: Defining environment variables in this manner is temporary for the life of the shell session. Setting permanent environment variables is outside the scope of these docs. With our environment variable defined, we start the app and consume the values. Remember that the `NODE_ENV` variable will be set for you automatically. When you load the app in the browser and inspect the `<input>`, you will see its value set to `abcdef`, and the bold text will show the environment provided when using `npm start`: ```html <div> <small>You are running this application in <b>development</b> mode.</small> <form> <input type="hidden" value="abcdef" /> </form> </div> ``` Having access to the `NODE_ENV` is also useful for performing actions conditionally: ```js if (process.env.NODE_ENV !== 'production') { analytics.disable(); } ``` ## Integrating with a Node Backend Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/) for instructions on integrating an app with a Node backend running on another port, and using `fetch()` to access it. You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo). ## Proxying API Requests in Development >Note: this feature is available with `react-scripts@0.2.3` and higher. People often serve the front-end React app from the same host and port as their backend implementation. For example, a production setup might look like this after the app is deployed: ``` / - static server returns index.html with React app /todos - static server returns index.html with React app /api/todos - server handles any /api/* requests using the backend implementation ``` Such setup is **not** required. However, if you **do** have a setup like this, it is convenient to write requests like `fetch('/api/todos')` without worrying about redirecting them to another host or port during development. To tell the development server to proxy any unknown requests to your API server in development, add a `proxy` field to your `package.json`, for example: ```js "proxy": "http://localhost:4000", ``` This way, when you `fetch('/api/todos')` in development, the development server will recognize that it’s not a static asset, and will proxy your request to `http://localhost:4000/api/todos` as a fallback. Conveniently, this avoids [CORS issues](http://stackoverflow.com/questions/21854516/understanding-ajax-cors-and-security-considerations) and error messages like this in development: ``` Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. ``` Keep in mind that `proxy` only has effect in development (with `npm start`), and it is up to you to ensure that URLs like `/api/todos` point to the right thing in production. You don’t have to use the `/api` prefix. Any unrecognized request will be redirected to the specified `proxy`. Currently the `proxy` option only handles HTTP requests, and it won’t proxy WebSocket connections. If the `proxy` option is **not** flexible enough for you, alternatively you can: * Enable CORS on your server ([here’s how to do it for Express](http://enable-cors.org/server_expressjs.html)). * Use [environment variables](#adding-custom-environment-variables) to inject the right server host and port into your app. ## Deployment By default, Create React App produces a build assuming your app is hosted at the server root. To override this, specify the `homepage` in your `package.json`, for example: ```js "homepage": "http://mywebsite.com/relativepath", ``` This will let Create React App correctly infer the root path to use in the generated HTML file. ### Now See [this example](https://github.com/xkawi/create-react-app-now) for a zero-configuration single-command deployment with [now](https://zeit.co/now). ### Heroku Use the [Heroku Buildpack for Create React App](https://github.com/mars/create-react-app-buildpack). You can find instructions in [Deploying React with Zero Configuration](https://blog.heroku.com/deploying-react-with-zero-configuration). ### Surge Install the Surge CLI if you haven't already by running `npm install -g surge`. Run the `surge` command and log in you or create a new account. You just need to specify the *build* folder and your custom domain, and you are done. ```sh email: email@domain.com password: ******** project path: /path/to/project/build size: 7 files, 1.8 MB domain: create-react-app.surge.sh upload: [====================] 100%, eta: 0.0s propagate on CDN: [====================] 100% plan: Free users: email@domain.com IP Address: X.X.X.X Success! Project is published and running at create-react-app.surge.sh ``` Note that in order to support routers that use html5 `pushState` API, you may want to rename the `index.html` in your build folder to `200.html` before deploying to Surge. This [ensures that every URL falls back to that file](https://surge.sh/help/adding-a-200-page-for-client-side-routing). ### GitHub Pages >Note: this feature is available with `react-scripts@0.2.0` and higher. Open your `package.json` and add a `homepage` field: ```js "homepage": "http://myusername.github.io/my-app", ``` **The above step is important!** Create React App uses the `homepage` field to determine the root URL in the built HTML file. Now, whenever you run `npm run build`, you will see a cheat sheet with a sequence of commands to deploy to GitHub pages: ```sh git commit -am "Save local changes" git checkout -B gh-pages git add -f build git commit -am "Rebuild website" git filter-branch -f --prune-empty --subdirectory-filter build git push -f origin gh-pages git checkout - ``` You may copy and paste them, or put them into a custom shell script. You may also customize them for another hosting provider. Note that GitHub Pages doesn't support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is because when there is a fresh page load for a url like `http://user.github.io/todomvc/todos/42`, where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions: * You could switch from using HTML5 history API to routing with hashes. If you use React Router, you can switch to `hashHistory` for this effect, but the URL will be longer and more verbose (for example, `http://user.github.io/todomvc/#/todos/42?_k=yknaj`). [Read more](https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#histories) about different history implementations in React Router. * Alternatively, you can use a trick to teach GitHub Pages to handle 404 by redirecting to your `index.html` page with a special redirect parameter. You would need to add a `404.html` file with the redirection code to the `build` folder before deploying your project, and you’ll need to add code handling the redirect parameter to `index.html`. You can find a detailed explanation of this technique [in this guide](https://github.com/rafrex/spa-github-pages). ## Something Missing? If you have ideas for more “How To” recipes that should be on this page, [let us know](https://github.com/facebookincubator/create-react-app/issues) or [contribute some!](https://github.com/facebookincubator/create-react-app/edit/master/template/README.md)
buildo / AvengerA CQRS-flavoured data fetching and caching layer in TypeScript. Batching, caching, data-dependencies and manual invalidations in a declarative fashion for Node and the browser
prashanthpai / SqlcacheCaching middleware for database/sql
jonascarpay / Declarative CachixManage cachix caches declaratively
adamgordonbell / Attribute Based CachingCache expensive methods calls with a declarative attribute. No custom code required. Configure caching method.
Juicy / Imported TemplateCustom element that lets you load template from external file into your document, and take full control over loaded <script>s and <link rel="import">s. Thanks to HTML Imports - caching, script execution, etc. is completely native. Declarative way for client-side includes boosted with HTML Imports features.
SOYJUN / Application With Raw IP SocketsOverview For this assignment you will be developing an application that uses raw IP sockets to ‘walk’ around an ordered list of nodes (given as a command line argument at the ‘source’ node, which is the node at which the tour was initiated), in a manner similar to the IP SSRR (Strict Source and Record Route) option. At each node, the application pings the preceding node in the tour. However, unlike the ping code in Stevens, you will be sending the ping ICMP echo request messages through a SOCK_RAW-type PF_PACKET socket and implementing ARP functionality to find the Ethernet address of the target node. Finally, when the ‘walk’ is completed, the group of nodes visited on the tour will exchange multicast messages. Your code will consist of two process modules, a ‘Tour’ application module (which will implement all the functionality outlined above, except for ARP activity) and an ARP module. The following should prove to be useful reference material for the assignment: Sections 21.2, 21.3, 21.6 and 21.10, Chapter 21, on Multicasting. Sections 27.1 to 27.3, Chapter 27, on the IP SSRR option. Sections 28.1 to 28.5, Chapter 28, on raw sockets, the IP_HDRINCL socket option, and ping. Sections 15.5, Chapter 15, on Unix domain SOCK_STREAM sockets. Figure 29.14, p. 807, and the corresponding explanation on p. 806, on filling in an IP header when the IP_HDRINCL socket option is in effect. The Lecture Slides on ARP & RARP (especially Section 4.4, ARP Packet Format, and the Figure 4.3 it includes). The link http://www.pdbuchan.com/rawsock/rawsock.html contains useful code samples that use IP raw sockets and PF_PACKET sockets. Note, in partcular, the code “icmp4_ll.c” in Table 2 for building an echo request sent through a PF_PACKET SOCK_RAW socket. The VMware environment You will be using the same vm1 , . . . . . , vm10 nodes you used for Assignment 3. However, unlike Assignment 3, you should use only interfaces eth0 and their associated IP addresses and ignore the other Ethernet interfaces that nodes have (interfaces eth0 make vm1 , . . . . . , vm10 look as if they belong to the same Ethernet LAN segment IP network 130.245.156.0/24). Note that, apart from the primary IP addresses associated with interfaces eth0, some nodes might also have one or more alias IP addresses associated with their interface eth0. Tour application module specifications The application will create a total of four sockets: two IP raw sockets, a PF_PACKET socket and a UDP socket for multicasting. We shall call the two IP raw sockets the ‘rt ’ (‘route traversal’) and ‘pg ’ (‘ping’) sockets, respectively. The rt socket should have the IP_HDRINCL option set. You will only be receiving ICMP echo reply messages through the pg socket (and not sending echo requests), so it does not matter whether it has the IP_HDRINCL option set or not. The pg socket should have protocol value (i.e., protocol demultiplexing key in the IP header) IPPROTO_ICMP. The rt socket should have a protocol value that identifies the application - i.e., some value other than the IPPROTO_XXXX values in /usr/include/netinet/in.h. However, remember that you will all be running your code using the same root account on the vm1 , . . . . . , vm10 nodes. So if two of you happen to choose the same protocol value and happen to be running on the same vm node at the same time, your applications will receive each other’s IP packets. For that reason, try to choose a protocol value for your rt socket that is likely to be unique to yourself. The PF_PACKET socket should be of type SOCK_RAW (not SOCK_DGRAM). This socket should have a protocol value of ETH_P_IP = 0x0800 (IPv4). The UDP socket for multicasting will be discussed below. Note that, depending on how you choose to bind that socket, you might actually need to have two UDP sockets for multicast communication – see bottom of p. 576, Section 21.10. Your application will, of course, have to be running on every vm node that is included in the tour. When evoking the application on the source node, the user supplies a sequence of vm node names (not IP addresses) to be visited in order. This command line sequence starts with the next node to be visited from the source node (i.e., it does not start with the source node itself). The sequence can include any number of repeated visits to the same node. For example, suppose that the source node is vm3 and the executable is called badr_tour : [root@vm3/root]# badr_tour vm2 vm10 vm4 vm7 vm5 vm2 vm6 vm2 vm9 vm4 vm7 vm2 vm6 vm5 vm1 vm10 vm8 (but note that the tour does not necessarily have to visit every vm node; and the same node should not appear consequentively in the tour list – i.e., the next node on the tour cannot be the current node itself). The application turns the sequence into a list of IP addresses for source routing. It also adds the IP address of the source node itself to the beginning of the list. The list thus produced will be carried as the payload of an IP packet, not as a SSRR option in the packet header. It is our application which will ensure that every node in the sequence is visited in order, not the IP SSRR capability. The source node should also add to the list an IP multicast address and a port number of its choice. It should also join the multicast group at that address and port number on its UDP socket. The TTL for outgoing multicasts should be set to 1. The application then fills in the header of an IP packet, designating itself as the IP source, and the next node to be visited as the IP destination. The packet is sent out on the rt socket. Note that on Linux, all the fields of the packet header must be in network byte order (Stevens, Section 28.3, p. 737, the fourth bullet point). When filling in the packet header, you should explicitly fill in the identification field (recall that, with the IP_HDRINCL socket option, if the identification field is given value 0, then the kernel will set its value). Try to make sure that the value you choose is likely to be unique to yourself (for reasons similar to those explained with respect to the IPPROTO_XXXX in 1. above). When a node receives an IP packet on its rt socket, it should first check that the identification field carries the right value (this implies that you will hard code your choice of identification field value determined in item 2 above in your code). If the identification field value does not check out, the packet is ignored. For a valid packet : Print out a message along the lines of: <time> received source routing packet from <hostname> <time> is the current time in human-readable format (see lines 19 & 20 in Figure 1.9, p. 14, and the corresponding explanation on p. 14f.), and <hostname> is the host name corresponding to the source IP address in the header of the received packet. If this is the first time the node is visited, the application should use the multicast address and port number in the packet received to join the multicast group on its UDP socket. The TTL for outgoing multicasts should be set to 1. The application updates the list in the payload, so that the next node in the tour can easily identify what the next hop from itself will be when it receives the packet. How you do this I leave up to you. You could, for example, include as part of the payload a pointer field into the list of nodes to be visited. This pointer would then be updated to the next entry in the list as the packet progresses hop by hop (see Figure 27.1 and the associated explanation on pp. 711-712). Other solutions are, of course, possible. The application then fills in a new IP header, designating itself as the IP source, and the next node to be visited as the IP destination. The identification field should be set to the same value as in the received packet. The packet is sent out on the rt socket. The node should also initiate pinging to the preceding node in the tour (the IP address of which it should pick up from the header of the received packet). However, unlike the Stevens ping code, it will be using the SOCK_RAW-type PF_PACKET socket of item 1 above to send the ICMP echo request messages. Before it can send echo request messages, the application has to call on the ARP module you will implement to get the Ethernet address of this preceding / ‘target’ node; this call is made using the API function areq which you will also implement (see sections ARP module specifications & API specifications below). Note that ARP has to be evoked every time the application wants to send out an echo request message, and not just the first time. An echo request message has to be encapsulated in a properly-formulated IP packet, which is in turn encapsulated in a properly-formulated Ethernet frame transmitted out through the PF_PACKET socket ; otherwise, ICMP at the source node will not receive it. You will have to modify Stevens’ ping code accordingly, specifically, the send_v4 function. In particular, the Ethernet frame must have a value of ETH_P_IP = 0x0800 (IPv4 – see <linux/if_ether.h>) in the frame type / ‘length’ field ; and the encapsulated IP packet must have a value of IPPROTO_ICMP = 0x01 (ICMPv4 – see <netinet_in.h>) in its protocol field. You should also simplify the ping code in its entirety by stripping all the ‘indirection’ IPv4 / IPv6 dual-operability paraphernalia and making the code work just for IPv4. Also note that the functions host_serv and freeaddrinfo, together with the associated structure addrinfo (see Sections 11.6, 11.8 & 11.11), in Figures 27.3, 27.6 & 28.5 ( pp. 713, 716 & 744f., respectively) can be replaced by the function gethostbyname and associated structure hostent (see Section 11.3) where needed. Also, there is no ‘-v’ verbose option, so this too should be stripped from Stevens’ code. When a node is ready to start pinging, it first prints out a ‘PING’ message similar to lines 32-33 of Figure 28.5, p. 744. It then builds up ICMP echo request messages and sends them to the source node every 1 second through the PF_PACKET socket. It also reads incoming echo response messages off the pg socket, in response to which it prints out the same kind of output as the code of Figure 28.8, p. 748. If this node and its preceding node have been previously visited in that order during the tour, then pinging would have already been initiated from the one to the other in response to the first visit, and nothing further should nor need be done during second and subsequent visits. In light of the above, note that once a node initiates pinging, it needs to read from both its rt and pg sockets, necessitating the use of the select function. As will be clear from what follows below, the application will anyway be needing also to simultaneously monitor its UDP socket for incoming multicast datagrams. When the last node on the tour is reached, and if this is the first time it is visited, it joins the multicast group and starts pinging the preceding node (if it is not already doing so). After a few echo replies are received (five, say), it sends out the multicast message below on its UDP socket (i.e., the node should wait about five seconds before sending the multicast message) : <<<<< This is node vmi . Tour has ended . Group members please identify yourselves. >>>>> where vmi is the name (not IP address) of the node. The node should also print this message out on stdout preceded, on the same line, by the phrase: Node vmi . Sending: <then print out the message sent>. Each node vmj receiving this message should print out the message received preceded, on the same line, by the phrase: Node vmj . Received <then print out the message received>. Each such node in step a above should then immediately stop its pinging activity. The node should then send out the following multicast message: <<<<< Node vmj . I am a member of the group. >>>>> and print out this message preceded, on the same line, by the phrase: Node vmj . Sending: <then print out the message sent>. Each node receiving these second multicast messages (i.e., the messages that nodes – including itself – sent out in step c above) should print each such message out preceded, on the same line, by the phrase: Node vmk . Received: <then print out the message received>. Reading from the socket in step d above should be implemented with a 5-second timeout. When the timeout expires, the node should print out another message to the effect that it is terminating the Tour application, and gracefully exit its Tour process. Note that under Multicast specifications, the last node in the tour, which sends out the End of Tour message, should itself receive a copy of that message and, when it does, it should behave exactly as do the other nodes in steps a. – e. above. ARP module specifications Your executable is evoked with no command line arguments. Like the Tour module, it will be running on every vm node. It uses the get_hw_addrs function of Assignment 3 to explore its node’s interfaces and build a set of <IP address , HW address> matching pairs for all eth0 interface IP addresses (including alias IP addresses, if any). Write out to stdout in some appropriately clear format the address pairs found. The module creates two sockets: a PF_PACKET socket and a Unix domain socket. The PF_PACKET should be of type SOCK_RAW (not type SOCK_DGRAM) with a protocol value of your choice (but not one of the standard values defined in <linux/if_ether.h>) which is, hopefully, unique to yourself. This value effectively becomes the protocol value for your implementation of ARP. Because this protocol value will be carried in the frame type / ‘length’ field of the Ethernet frame header (see Figure 4.3 of the ARP & RARP handout), the value chosen should be not less than 1536 (0x600) so that it is not misinterpreted as the length of an Ethernet 802.3 frame. The Unix domain socket should be of type SOCK_STREAM (not SOCK_DGRAM). It is a listening socket bound to a ‘well-known’ sun_path file. This socket will be used to communicate with the function areq that is implemented in the Tour module (see the section API specifications below). In this context, areq will act as the client and the ARP module as the server. The ARP module then sits in an infinite loop, monitoring these two sockets. As ARP request messages arrive on the PF_PACKET socket, the module processes them, and responds with ARP reply messages as appropriate. The protocol builds a ‘cache’ of matching <IP address , HW address> pairs from the replies (and requests – see below) it receives. For simplicity, and unlike the real ARP, we shall not implement timing out mechanisms for these cache entries. A cache entry has five parts: (i) IP address ; (ii) HW address ; (iii) sll_ifindex (the interface to be used for reaching the matching pair <(i) , (ii)>) ; (iv) sll_hatype ; and (v) a Unix-domain connection-socket descriptor for a connected client (see the section API specifications below for the latter three). When an ARP reply is being entered in the cache, the ARP module uses the socket descriptor in (v) to send a reply to the client, closes the connection socket, and deletes the socket descriptor from the cache entry. Note that, like the real ARP, when an ARP request is received by a node, and if the request pertains to that receiving node, the sender’s (see Figure 4.3 of the ARP & RARP handout) <IP address, HW address> matching pair should be entered into the cache if it is not already there (together, of course, with (iii) sll_ifindex & (iv) sll_hatype), or updated if need be if such an entry already exists in the cache. If the ARP request received does not pertain to the node receiving it, but there is already an entry in that receiving node's cache for the sender’s <IP address, HW address> matching pair, that entry should be checked and updated if need be. If there is no such entry, no action is taken (in particular, and unlike the case above, no new entry should be made in the receiving node's cache of the sender’s <IP address, HW address> matching pair if such an entry does not already exist). ARP request and reply messages have the same format as Figure 4.3 of the ARP & RARP handout, but with an extra 2-byte identification field added at the beginning which you fill with a value chosen so that it has a high probability of being unique to yourself. This value is to be echoed in the reply message, and helps to act as a further filter in case some other student happens to have fortuitously chosen the same value as yourself for the protocol parameter of the ARP PF_PACKET. Values in the fields of our ARP messages must be in network byte order. You might find the system header file <linux/if_arp.h> useful for manipulating ARP request and reply messages, but remember that our version of these messages have an extra two-byte field as mentioned above. Your code should print out on stdout, in some appropriately clear format, the contents of the Ethernet frame header and ARP request message you send. As described in Section 4.4 of the ARP & RARP handout, the node that responds to the request should, in its reply message, swap the two sender addresses with the two target addresses, as well as, of course, echo back the extra identification field sent with the request. The protocol at this responding node should print out, in an appropriately clear format, both the request frame (header and ARP message) it receives and the reply frame it sends. Similarly, the node that sent the request should print out the reply frame it receives. Finally, recall that the node issuing the request sends out a broadcast Ethernet frame, but the responding node replies with a unicast frame. API specifications The API is for communication between the Tour process and the ARP process. It consists of a single function, areq, implemented in the Tour module. areq is called by send_v4 function of the application every time the latter want to send out an ICMP echo request message: int areq (struct sockaddr *IPaddr, socklen_t sockaddrlen, struct hwaddr *HWaddr); IPaddr contains the primary or alias IPaddress of a ‘target’ node on the LAN for which the corresponding hardware address is being requested. hwaddr is a new structure (and not a pre-existing type) modeled on the sockaddr_ll of PF_PACKET; you will have to declare it in your code. It is used to return the requested hardware address to the caller of areq : structure hwaddr { int sll_ifindex; /* Interface number */ unsigned short sll_hatype; /* Hardware type */ unsigned char sll_halen; /* Length of address */ unsigned char sll_addr[8]; /* Physical layer address */ }; areq creates a Unix domain socket of type SOCK_STREAM and connects to the ‘well-known’ sun_path file of the ARP listening socket. It sends the IP address from parameter IPaddr and the information in the three fields of parameter HWaddr to ARP. It then blocks on a read awaiting a reply from ARP. This read should be backed up by a timeout since it is possible that no reply is received for the request. If a timeout occurs, areq should close the socket and return to its caller indicating failure (through its int return value). Your application code should print out on stdout, in some appropriately clear format, a notification every time areq is called, giving the IP address for which a HW address is being sought. It should similarly print out the result when the call to areq returns (HW address returned, or failure). When the ARP module receives a request for a HW address from areq through its Unix domain listening socket, it first checks if the required HW address is already in the cache. If so, it can respond immediately to the areq and close the Unix domain connection socket. Else : it makes an ‘incomplete’ entry in the cache, consisting of parts (i), (iii), (iv) and (v) ; puts out an ARP request message on the network on its PF_PACKET socket; and starts monitoring the areq connection socket for readability – if the areq client closes the connection socket (this would occur in response to a timeout in areq), ARP deletes the corresponding incomplete entry from the cache (and ignores any subsequent ARP reply from the network if such is received). On the other hand, if ARP receives a reply from the network, it updates the incomplete cache entry, responds to areq, and closes the connection socket.
questionmark1122 / Cnn10#!bash # # bash completion support for core Git. # # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org> # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). # Distributed under the GNU General Public License, version 2.0. # # The contained completion routines provide support for completing: # # *) local and remote branch names # *) local and remote tag names # *) .git/remotes file names # *) git 'subcommands' # *) tree paths within 'ref:path/to/file' expressions # *) common --long-options # # To use these routines: # # 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). # 2) Added the following line to your .bashrc: # source ~/.git-completion.sh # # 3) Consider changing your PS1 to also show the current branch: # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' # # The argument to __git_ps1 will be displayed only if you # are currently in a git repository. The %s token will be # the name of the current branch. # # In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty # value, unstaged (*) and staged (+) changes will be shown next # to the branch name. You can configure this per-repository # with the bash.showDirtyState variable, which defaults to true # once GIT_PS1_SHOWDIRTYSTATE is enabled. # # You can also see if currently something is stashed, by setting # GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, # then a '$' will be shown next to the branch name. # # If you would like to see if there're untracked files, then you can # set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're # untracked files, then a '%' will be shown next to the branch name. # # If you would like to see the difference between HEAD and its # upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates # you are behind, ">" indicates you are ahead, and "<>" # indicates you have diverged. You can further control # behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated # list of values: # verbose show number of commits ahead/behind (+/-) upstream # legacy don't use the '--count' option available in recent # versions of git-rev-list # git always compare HEAD to @{upstream} # svn always compare HEAD to your SVN upstream # By default, __git_ps1 will compare HEAD to your SVN upstream # if it can find one, or @{upstream} otherwise. Once you have # set GIT_PS1_SHOWUPSTREAM, you can override it on a # per-repository basis by setting the bash.showUpstream config # variable. # # # To submit patches: # # *) Read Documentation/SubmittingPatches # *) Send all patches to the current maintainer: # # "Shawn O. Pearce" <spearce@spearce.org> # # *) Always CC the Git mailing list: # # git@vger.kernel.org # case "$COMP_WORDBREAKS" in *:*) : great ;; *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" esac # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo __gitdir () { if [ -z "${1-}" ]; then if [ -n "${__git_dir-}" ]; then echo "$__git_dir" elif [ -d .git ]; then echo .git else git rev-parse --git-dir 2>/dev/null fi elif [ -d "$1/.git" ]; then echo "$1/.git" else echo "$1" fi } # stores the divergence from upstream in $p # used by GIT_PS1_SHOWUPSTREAM __git_ps1_show_upstream () { local key value local svn_remote=() svn_url_pattern count n local upstream=git legacy="" verbose="" # get some config options from git-config while read key value; do case "$key" in bash.showupstream) GIT_PS1_SHOWUPSTREAM="$value" if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then p="" return fi ;; svn-remote.*.url) svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" svn_url_pattern+="\\|$value" upstream=svn+git # default upstream is SVN if available, else git ;; esac done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ') # parse configuration values for option in ${GIT_PS1_SHOWUPSTREAM}; do case "$option" in git|svn) upstream="$option" ;; verbose) verbose=1 ;; legacy) legacy=1 ;; esac done # Find our upstream case "$upstream" in git) upstream="@{upstream}" ;; svn*) # get the upstream from the "git-svn-id: ..." in a commit message # (git-svn uses essentially the same procedure internally) local svn_upstream=($(git log --first-parent -1 \ --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null)) if [[ 0 -ne ${#svn_upstream[@]} ]]; then svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} svn_upstream=${svn_upstream%@*} for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do svn_upstream=${svn_upstream#${svn_remote[$n]}} done if [[ -z "$svn_upstream" ]]; then # default branch name for checkouts with no layout: upstream=${GIT_SVN_ID:-git-svn} else upstream=${svn_upstream#/} fi elif [[ "svn+git" = "$upstream" ]]; then upstream="@{upstream}" fi ;; esac # Find how many commits we are ahead/behind our upstream if [[ -z "$legacy" ]]; then count="$(git rev-list --count --left-right \ "$upstream"...HEAD 2>/dev/null)" else # produce equivalent output to --count for older versions of git local commits if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" then local commit behind=0 ahead=0 for commit in $commits do case "$commit" in "<"*) let ++behind ;; *) let ++ahead ;; esac done count="$behind $ahead" else count="" fi fi # calculate the result if [[ -z "$verbose" ]]; then case "$count" in "") # no upstream p="" ;; "0 0") # equal to upstream p="=" ;; "0 "*) # ahead of upstream p=">" ;; *" 0") # behind upstream p="<" ;; *) # diverged from upstream p="<>" ;; esac else case "$count" in "") # no upstream p="" ;; "0 0") # equal to upstream p=" u=" ;; "0 "*) # ahead of upstream p=" u+${count#0 }" ;; *" 0") # behind upstream p=" u-${count% 0}" ;; *) # diverged from upstream p=" u+${count#* }-${count% *}" ;; esac fi } # __git_ps1 accepts 0 or 1 arguments (i.e., format string) # returns text to add to bash PS1 prompt (includes branch name) __git_ps1 () { local g="$(__gitdir)" if [ -n "$g" ]; then local r="" local b="" if [ -f "$g/rebase-merge/interactive" ]; then r="|REBASE-i" b="$(cat "$g/rebase-merge/head-name")" elif [ -d "$g/rebase-merge" ]; then r="|REBASE-m" b="$(cat "$g/rebase-merge/head-name")" else if [ -d "$g/rebase-apply" ]; then if [ -f "$g/rebase-apply/rebasing" ]; then r="|REBASE" elif [ -f "$g/rebase-apply/applying" ]; then r="|AM" else r="|AM/REBASE" fi elif [ -f "$g/MERGE_HEAD" ]; then r="|MERGING" elif [ -f "$g/BISECT_LOG" ]; then r="|BISECTING" fi b="$(git symbolic-ref HEAD 2>/dev/null)" || { b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains) git describe --contains HEAD ;; (branch) git describe --contains --all HEAD ;; (describe) git describe HEAD ;; (* | default) git describe --exact-match HEAD ;; esac 2>/dev/null)" || b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || b="unknown" b="($b)" } fi local w="" local i="" local s="" local u="" local c="" local p="" if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then c="BARE:" else b="GIT_DIR!" fi elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then git diff --no-ext-diff --quiet --exit-code || w="*" if git rev-parse --quiet --verify HEAD >/dev/null; then git diff-index --cached --quiet HEAD -- || i="+" else i="#" fi fi fi if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" fi if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then if [ -n "$(git ls-files --others --exclude-standard)" ]; then u="%" fi fi if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then __git_ps1_show_upstream fi fi local f="$w$i$s$u" printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" fi } # __gitcomp_1 requires 2 arguments __gitcomp_1 () { local c IFS=' '$'\t'$'\n' for c in $1; do case "$c$2" in --*=*) printf %s$'\n' "$c$2" ;; *.) printf %s$'\n' "$c$2" ;; *) printf %s$'\n' "$c$2 " ;; esac done } # __gitcomp accepts 1, 2, 3, or 4 arguments # generates completion reply with compgen __gitcomp () { local cur="${COMP_WORDS[COMP_CWORD]}" if [ $# -gt 2 ]; then cur="$3" fi case "$cur" in --*=) COMPREPLY=() ;; *) local IFS=$'\n' COMPREPLY=($(compgen -P "${2-}" \ -W "$(__gitcomp_1 "${1-}" "${4-}")" \ -- "$cur")) ;; esac } # __git_heads accepts 0 or 1 arguments (to pass to __gitdir) __git_heads () { local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/heads return fi for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_tags accepts 0 or 1 arguments (to pass to __gitdir) __git_tags () { local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/tags return fi for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_refs accepts 0 or 1 arguments (to pass to __gitdir) __git_refs () { local i is_hash=y dir="$(__gitdir "${1-}")" local cur="${COMP_WORDS[COMP_CWORD]}" format refs if [ -d "$dir" ]; then case "$cur" in refs|refs/*) format="refname" refs="${cur%/*}" ;; *) for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do if [ -e "$dir/$i" ]; then echo $i; fi done format="refname:short" refs="refs/tags refs/heads refs/remotes" ;; esac git --git-dir="$dir" for-each-ref --format="%($format)" \ $refs return fi for i in $(git ls-remote "$dir" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;; n,*) is_hash=y; echo "$i" ;; esac done } # __git_refs2 requires 1 argument (to pass to __git_refs) __git_refs2 () { local i for i in $(__git_refs "$1"); do echo "$i:$i" done } # __git_refs_remotes requires 1 argument (to pass to ls-remote) __git_refs_remotes () { local cmd i is_hash=y for i in $(git ls-remote "$1" 2>/dev/null); do case "$is_hash,$i" in n,refs/heads/*) is_hash=y echo "$i:refs/remotes/$1/${i#refs/heads/}" ;; y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y;; n,*) is_hash=y; ;; esac done } __git_remotes () { local i ngoff IFS=$'\n' d="$(__gitdir)" shopt -q nullglob || ngoff=1 shopt -s nullglob for i in "$d/remotes"/*; do echo ${i#$d/remotes/} done [ "$ngoff" ] && shopt -u nullglob for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do i="${i#remote.}" echo "${i/.url*/}" done } __git_list_merge_strategies () { git merge -s help 2>&1 | sed -n -e '/[Aa]vailable strategies are: /,/^$/{ s/\.$// s/.*:// s/^[ ]*// s/[ ]*$// p }' } __git_merge_strategies= # 'git merge -s help' (and thus detection of the merge strategy # list) fails, unfortunately, if run outside of any git working # tree. __git_merge_strategies is set to the empty string in # that case, and the detection will be repeated the next time it # is needed. __git_compute_merge_strategies () { : ${__git_merge_strategies:=$(__git_list_merge_strategies)} } __git_complete_file () { local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in ?*:*) ref="${cur%%:*}" cur="${cur#*:}" case "$cur" in ?*/*) pfx="${cur%/*}" cur="${cur##*/}" ls="$ref:$pfx" pfx="$pfx/" ;; *) ls="$ref" ;; esac case "$COMP_WORDBREAKS" in *:*) : great ;; *) pfx="$ref:$pfx" ;; esac local IFS=$'\n' COMPREPLY=($(compgen -P "$pfx" \ -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ | sed '/^100... blob /{ s,^.* ,, s,$, , } /^120000 blob /{ s,^.* ,, s,$, , } /^040000 tree /{ s,^.* ,, s,$,/, } s/^.* //')" \ -- "$cur")) ;; *) __gitcomp "$(__git_refs)" ;; esac } __git_complete_revlist () { local pfx cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in *...*) pfx="${cur%...*}..." cur="${cur#*...}" __gitcomp "$(__git_refs)" "$pfx" "$cur" ;; *..*) pfx="${cur%..*}.." cur="${cur#*..}" __gitcomp "$(__git_refs)" "$pfx" "$cur" ;; *) __gitcomp "$(__git_refs)" ;; esac } __git_complete_remote_or_refspec () { local cmd="${COMP_WORDS[1]}" local cur="${COMP_WORDS[COMP_CWORD]}" local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0 while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;; --all) case "$cmd" in push) no_complete_refspec=1 ;; fetch) COMPREPLY=() return ;; *) ;; esac ;; -*) ;; *) remote="$i"; break ;; esac c=$((++c)) done if [ -z "$remote" ]; then __gitcomp "$(__git_remotes)" return fi if [ $no_complete_refspec = 1 ]; then COMPREPLY=() return fi [ "$remote" = "." ] && remote= case "$cur" in *:*) case "$COMP_WORDBREAKS" in *:*) : great ;; *) pfx="${cur%%:*}:" ;; esac cur="${cur#*:}" lhs=0 ;; +*) pfx="+" cur="${cur#+}" ;; esac case "$cmd" in fetch) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur" else __gitcomp "$(__git_refs)" "$pfx" "$cur" fi ;; pull) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" else __gitcomp "$(__git_refs)" "$pfx" "$cur" fi ;; push) if [ $lhs = 1 ]; then __gitcomp "$(__git_refs)" "$pfx" "$cur" else __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur" fi ;; esac } __git_complete_strategy () { __git_compute_merge_strategies case "${COMP_WORDS[COMP_CWORD-1]}" in -s|--strategy) __gitcomp "$__git_merge_strategies" return 0 esac local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --strategy=*) __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" return 0 ;; esac return 1 } __git_list_all_commands () { local i IFS=" "$'\n' for i in $(git help -a|egrep '^ [a-zA-Z0-9]') do case $i in *--*) : helper pattern;; *) echo $i;; esac done } __git_all_commands= __git_compute_all_commands () { : ${__git_all_commands:=$(__git_list_all_commands)} } __git_list_porcelain_commands () { local i IFS=" "$'\n' __git_compute_all_commands for i in "help" $__git_all_commands do case $i in *--*) : helper pattern;; applymbox) : ask gittus;; applypatch) : ask gittus;; archimport) : import;; cat-file) : plumbing;; check-attr) : plumbing;; check-ref-format) : plumbing;; checkout-index) : plumbing;; commit-tree) : plumbing;; count-objects) : infrequent;; cvsexportcommit) : export;; cvsimport) : import;; cvsserver) : daemon;; daemon) : daemon;; diff-files) : plumbing;; diff-index) : plumbing;; diff-tree) : plumbing;; fast-import) : import;; fast-export) : export;; fsck-objects) : plumbing;; fetch-pack) : plumbing;; fmt-merge-msg) : plumbing;; for-each-ref) : plumbing;; hash-object) : plumbing;; http-*) : transport;; index-pack) : plumbing;; init-db) : deprecated;; local-fetch) : plumbing;; lost-found) : infrequent;; ls-files) : plumbing;; ls-remote) : plumbing;; ls-tree) : plumbing;; mailinfo) : plumbing;; mailsplit) : plumbing;; merge-*) : plumbing;; mktree) : plumbing;; mktag) : plumbing;; pack-objects) : plumbing;; pack-redundant) : plumbing;; pack-refs) : plumbing;; parse-remote) : plumbing;; patch-id) : plumbing;; peek-remote) : plumbing;; prune) : plumbing;; prune-packed) : plumbing;; quiltimport) : import;; read-tree) : plumbing;; receive-pack) : plumbing;; reflog) : plumbing;; remote-*) : transport;; repo-config) : deprecated;; rerere) : plumbing;; rev-list) : plumbing;; rev-parse) : plumbing;; runstatus) : plumbing;; sh-setup) : internal;; shell) : daemon;; show-ref) : plumbing;; send-pack) : plumbing;; show-index) : plumbing;; ssh-*) : transport;; stripspace) : plumbing;; symbolic-ref) : plumbing;; tar-tree) : deprecated;; unpack-file) : plumbing;; unpack-objects) : plumbing;; update-index) : plumbing;; update-ref) : plumbing;; update-server-info) : daemon;; upload-archive) : plumbing;; upload-pack) : plumbing;; write-tree) : plumbing;; var) : infrequent;; verify-pack) : infrequent;; verify-tag) : plumbing;; *) echo $i;; esac done } __git_porcelain_commands= __git_compute_porcelain_commands () { __git_compute_all_commands : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)} } __git_aliases () { local i IFS=$'\n' for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do case "$i" in alias.*) i="${i#alias.}" echo "${i/ */}" ;; esac done } # __git_aliased_command requires 1 argument __git_aliased_command () { local word cmdline=$(git --git-dir="$(__gitdir)" \ config --get "alias.$1") for word in $cmdline; do case "$word" in \!gitk|gitk) echo "gitk" return ;; \!*) : shell command alias ;; -*) : option ;; *=*) : setting env ;; git) : git itself ;; *) echo "$word" return esac done } # __git_find_on_cmdline requires 1 argument __git_find_on_cmdline () { local word subcommand c=1 while [ $c -lt $COMP_CWORD ]; do word="${COMP_WORDS[c]}" for subcommand in $1; do if [ "$subcommand" = "$word" ]; then echo "$subcommand" return fi done c=$((++c)) done } __git_has_doubledash () { local c=1 while [ $c -lt $COMP_CWORD ]; do if [ "--" = "${COMP_WORDS[c]}" ]; then return 0 fi c=$((++c)) done return 1 } __git_whitespacelist="nowarn warn error error-all fix" _git_am () { local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" if [ -d "$dir"/rebase-apply ]; then __gitcomp "--skip --continue --resolved --abort" return fi case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --3way --committer-date-is-author-date --ignore-date --ignore-whitespace --ignore-space-change --interactive --keep --no-utf8 --signoff --utf8 --whitespace= --scissors " return esac COMPREPLY=() } _git_apply () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --stat --numstat --summary --check --index --cached --index-info --reverse --reject --unidiff-zero --apply --no-add --exclude= --ignore-whitespace --ignore-space-change --whitespace= --inaccurate-eof --verbose " return esac COMPREPLY=() } _git_add () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --interactive --refresh --patch --update --dry-run --ignore-errors --intent-to-add " return esac COMPREPLY=() } _git_archive () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --format=*) __gitcomp "$(git archive --list)" "" "${cur##--format=}" return ;; --remote=*) __gitcomp "$(__git_remotes)" "" "${cur##--remote=}" return ;; --*) __gitcomp " --format= --list --verbose --prefix= --remote= --exec= " return ;; esac __git_complete_file } _git_bisect () { __git_has_doubledash && return local subcommands="start bad good skip reset visualize replay log run" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" return fi case "$subcommand" in bad|good|reset|skip) __gitcomp "$(__git_refs)" ;; *) COMPREPLY=() ;; esac } _git_branch () { local i c=1 only_local_ref="n" has_r="n" while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in -d|-m) only_local_ref="y" ;; -r) has_r="y" ;; esac c=$((++c)) done case "${COMP_WORDS[COMP_CWORD]}" in --*) __gitcomp " --color --no-color --verbose --abbrev= --no-abbrev --track --no-track --contains --merged --no-merged --set-upstream " ;; *) if [ $only_local_ref = "y" -a $has_r = "n" ]; then __gitcomp "$(__git_heads)" else __gitcomp "$(__git_refs)" fi ;; esac } _git_bundle () { local cmd="${COMP_WORDS[2]}" case "$COMP_CWORD" in 2) __gitcomp "create list-heads verify unbundle" ;; 3) # looking for a file ;; *) case "$cmd" in create) __git_complete_revlist ;; esac ;; esac } _git_checkout () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --conflict=*) __gitcomp "diff3 merge" "" "${cur##--conflict=}" ;; --*) __gitcomp " --quiet --ours --theirs --track --no-track --merge --conflict= --orphan --patch " ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_cherry () { __gitcomp "$(__git_refs)" } _git_cherry_pick () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--edit --no-commit" ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_clean () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--dry-run --quiet" return ;; esac COMPREPLY=() } _git_clone () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --local --no-hardlinks --shared --reference --quiet --no-checkout --bare --mirror --origin --upload-pack --template= --depth " return ;; esac COMPREPLY=() } _git_commit () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --cleanup=*) __gitcomp "default strip verbatim whitespace " "" "${cur##--cleanup=}" return ;; --reuse-message=*) __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}" return ;; --reedit-message=*) __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}" return ;; --untracked-files=*) __gitcomp "all no normal" "" "${cur##--untracked-files=}" return ;; --*) __gitcomp " --all --author= --signoff --verify --no-verify --edit --amend --include --only --interactive --dry-run --reuse-message= --reedit-message= --reset-author --file= --message= --template= --cleanup= --untracked-files --untracked-files= --verbose --quiet " return esac COMPREPLY=() } _git_describe () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --all --tags --contains --abbrev= --candidates= --exact-match --debug --long --match --always " return esac __gitcomp "$(__git_refs)" } __git_diff_common_options="--stat --numstat --shortstat --summary --patch-with-stat --name-only --name-status --color --no-color --color-words --no-renames --check --full-index --binary --abbrev --diff-filter= --find-copies-harder --text --ignore-space-at-eol --ignore-space-change --ignore-all-space --exit-code --quiet --ext-diff --no-ext-diff --no-prefix --src-prefix= --dst-prefix= --inter-hunk-context= --patience --raw --dirstat --dirstat= --dirstat-by-file --dirstat-by-file= --cumulative " _git_diff () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex --base --ours --theirs $__git_diff_common_options " return ;; esac __git_complete_file } __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff tkdiff vimdiff gvimdiff xxdiff araxis p4merge " _git_difftool () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}" return ;; --*) __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex --base --ours --theirs --no-renames --diff-filter= --find-copies-harder --relative --ignore-submodules --tool=" return ;; esac __git_complete_file } __git_fetch_options=" --quiet --verbose --append --upload-pack --force --keep --depth= --tags --no-tags --all --prune --dry-run " _git_fetch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "$__git_fetch_options" return ;; esac __git_complete_remote_or_refspec } _git_format_patch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --thread=*) __gitcomp " deep shallow " "" "${cur##--thread=}" return ;; --*) __gitcomp " --stdout --attach --no-attach --thread --thread= --output-directory --numbered --start-number --numbered-files --keep-subject --signoff --signature --no-signature --in-reply-to= --cc= --full-index --binary --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= --inline --suffix= --ignore-if-in-upstream --subject-prefix= " return ;; esac __git_complete_revlist } _git_fsck () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --tags --root --unreachable --cache --no-reflogs --full --strict --verbose --lost-found " return ;; esac COMPREPLY=() } _git_gc () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--prune --aggressive" return ;; esac COMPREPLY=() } _git_gitk () { _gitk } _git_grep () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --cached --text --ignore-case --word-regexp --invert-match --full-name --extended-regexp --basic-regexp --fixed-strings --files-with-matches --name-only --files-without-match --max-depth --count --and --or --not --all-match " return ;; esac __gitcomp "$(__git_refs)" } _git_help () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--all --info --man --web" return ;; esac __git_compute_all_commands __gitcomp "$__git_all_commands attributes cli core-tutorial cvs-migration diffcore gitk glossary hooks ignore modules repository-layout tutorial tutorial-2 workflows " } _git_init () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --shared=*) __gitcomp " false true umask group all world everybody " "" "${cur##--shared=}" return ;; --*) __gitcomp "--quiet --bare --template= --shared --shared=" return ;; esac COMPREPLY=() } _git_ls_files () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --deleted --modified --others --ignored --stage --directory --no-empty-directory --unmerged --killed --exclude= --exclude-from= --exclude-per-directory= --exclude-standard --error-unmatch --with-tree= --full-name --abbrev --ignored --exclude-per-directory " return ;; esac COMPREPLY=() } _git_ls_remote () { __gitcomp "$(__git_remotes)" } _git_ls_tree () { __git_complete_file } # Options that go well for log, shortlog and gitk __git_log_common_options=" --not --all --branches --tags --remotes --first-parent --merges --no-merges --max-count= --max-age= --since= --after= --min-age= --until= --before= " # Options that go well for log and gitk (not shortlog) __git_log_gitk_options=" --dense --sparse --full-history --simplify-merges --simplify-by-decoration --left-right " # Options that go well for log and shortlog (not gitk) __git_log_shortlog_options=" --author= --committer= --grep= --all-match " __git_log_pretty_formats="oneline short medium full fuller email raw format:" __git_log_date_formats="relative iso8601 rfc2822 short local default raw" _git_log () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(git rev-parse --git-dir 2>/dev/null)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; --format=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--format=}" return ;; --date=*) __gitcomp "$__git_log_date_formats" "" "${cur##--date=}" return ;; --decorate=*) __gitcomp "long short" "" "${cur##--decorate=}" return ;; --*) __gitcomp " $__git_log_common_options $__git_log_shortlog_options $__git_log_gitk_options --root --topo-order --date-order --reverse --follow --full-diff --abbrev-commit --abbrev= --relative-date --date= --pretty= --format= --oneline --cherry-pick --graph --decorate --decorate= --walk-reflogs --parents --children $merge $__git_diff_common_options --pickaxe-all --pickaxe-regex " return ;; esac __git_complete_revlist } __git_merge_options=" --no-commit --no-stat --log --no-log --squash --strategy --commit --stat --no-squash --ff --no-ff --ff-only " _git_merge () { __git_complete_strategy && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "$__git_merge_options" return esac __gitcomp "$(__git_refs)" } _git_mergetool () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --tool=*) __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}" return ;; --*) __gitcomp "--tool=" return ;; esac COMPREPLY=() } _git_merge_base () { __gitcomp "$(__git_refs)" } _git_mv () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--dry-run" return ;; esac COMPREPLY=() } _git_name_rev () { __gitcomp "--tags --all --stdin" } _git_notes () { local subcommands="edit show" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then __gitcomp "$subcommands" return fi case "${COMP_WORDS[COMP_CWORD-1]}" in -m|-F) COMPREPLY=() ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_pull () { __git_complete_strategy && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --rebase --no-rebase $__git_merge_options $__git_fetch_options " return ;; esac __git_complete_remote_or_refspec } _git_push () { local cur="${COMP_WORDS[COMP_CWORD]}" case "${COMP_WORDS[COMP_CWORD-1]}" in --repo) __gitcomp "$(__git_remotes)" return esac case "$cur" in --repo=*) __gitcomp "$(__git_remotes)" "" "${cur##--repo=}" return ;; --*) __gitcomp " --all --mirror --tags --dry-run --force --verbose --receive-pack= --repo= " return ;; esac __git_complete_remote_or_refspec } _git_rebase () { local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then __gitcomp "--continue --skip --abort" return fi __git_complete_strategy && return case "$cur" in --whitespace=*) __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; --*) __gitcomp " --onto --merge --strategy --interactive --preserve-merges --stat --no-stat --committer-date-is-author-date --ignore-date --ignore-whitespace --whitespace= --autosquash " return esac __gitcomp "$(__git_refs)" } __git_send_email_confirm_options="always never auto cc compose" __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all" _git_send_email () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --confirm=*) __gitcomp " $__git_send_email_confirm_options " "" "${cur##--confirm=}" return ;; --suppress-cc=*) __gitcomp " $__git_send_email_suppresscc_options " "" "${cur##--suppress-cc=}" return ;; --smtp-encryption=*) __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" return ;; --*) __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to --compose --confirm= --dry-run --envelope-sender --from --identity --in-reply-to --no-chain-reply-to --no-signed-off-by-cc --no-suppress-from --no-thread --quiet --signed-off-by-cc --smtp-pass --smtp-server --smtp-server-port --smtp-encryption= --smtp-user --subject --suppress-cc= --suppress-from --thread --to --validate --no-validate" return ;; esac COMPREPLY=() } _git_stage () { _git_add } __git_config_get_set_variables () { local prevword word config_file= c=$COMP_CWORD while [ $c -gt 1 ]; do word="${COMP_WORDS[c]}" case "$word" in --global|--system|--file=*) config_file="$word" break ;; -f|--file) config_file="$word $prevword" break ;; esac prevword=$word c=$((--c)) done git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null | while read line do case "$line" in *.*=*) echo "${line/=*/}" ;; esac done } _git_config () { local cur="${COMP_WORDS[COMP_CWORD]}" local prv="${COMP_WORDS[COMP_CWORD-1]}" case "$prv" in branch.*.remote) __gitcomp "$(__git_remotes)" return ;; branch.*.merge) __gitcomp "$(__git_refs)" return ;; remote.*.fetch) local remote="${prv#remote.}" remote="${remote%.fetch}" __gitcomp "$(__git_refs_remotes "$remote")" return ;; remote.*.push) local remote="${prv#remote.}" remote="${remote%.push}" __gitcomp "$(git --git-dir="$(__gitdir)" \ for-each-ref --format='%(refname):%(refname)' \ refs/heads)" return ;; pull.twohead|pull.octopus) __git_compute_merge_strategies __gitcomp "$__git_merge_strategies" return ;; color.branch|color.diff|color.interactive|\ color.showbranch|color.status|color.ui) __gitcomp "always never auto" return ;; color.pager) __gitcomp "false true" return ;; color.*.*) __gitcomp " normal black red green yellow blue magenta cyan white bold dim ul blink reverse " return ;; help.format) __gitcomp "man info web html" return ;; log.date) __gitcomp "$__git_log_date_formats" return ;; sendemail.aliasesfiletype) __gitcomp "mutt mailrc pine elm gnus" return ;; sendemail.confirm) __gitcomp "$__git_send_email_confirm_options" return ;; sendemail.suppresscc) __gitcomp "$__git_send_email_suppresscc_options" return ;; --get|--get-all|--unset|--unset-all) __gitcomp "$(__git_config_get_set_variables)" return ;; *.*) COMPREPLY=() return ;; esac case "$cur" in --*) __gitcomp " --global --system --file= --list --replace-all --get --get-all --get-regexp --add --unset --unset-all --remove-section --rename-section " return ;; branch.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur" return ;; branch.*) local pfx="${cur%.*}." cur="${cur#*.}" __gitcomp "$(__git_heads)" "$pfx" "$cur" "." return ;; guitool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp " argprompt cmd confirm needsfile noconsole norescan prompt revprompt revunmerged title " "$pfx" "$cur" return ;; difftool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path" "$pfx" "$cur" return ;; man.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path" "$pfx" "$cur" return ;; mergetool.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "cmd path trustExitCode" "$pfx" "$cur" return ;; pager.*) local pfx="${cur%.*}." cur="${cur#*.}" __git_compute_all_commands __gitcomp "$__git_all_commands" "$pfx" "$cur" return ;; remote.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp " url proxy fetch push mirror skipDefaultUpdate receivepack uploadpack tagopt pushurl " "$pfx" "$cur" return ;; remote.*) local pfx="${cur%.*}." cur="${cur#*.}" __gitcomp "$(__git_remotes)" "$pfx" "$cur" "." return ;; url.*.*) local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur" return ;; esac __gitcomp " add.ignore-errors alias. apply.ignorewhitespace apply.whitespace branch.autosetupmerge branch.autosetuprebase clean.requireForce color.branch color.branch.current color.branch.local color.branch.plain color.branch.remote color.diff color.diff.commit color.diff.frag color.diff.meta color.diff.new color.diff.old color.diff.plain color.diff.whitespace color.grep color.grep.external color.grep.match color.interactive color.interactive.header color.interactive.help color.interactive.prompt color.pager color.showbranch color.status color.status.added color.status.changed color.status.header color.status.nobranch color.status.untracked color.status.updated color.ui commit.template core.autocrlf core.bare core.compression core.createObject core.deltaBaseCacheLimit core.editor core.excludesfile core.fileMode core.fsyncobjectfiles core.gitProxy core.ignoreCygwinFSTricks core.ignoreStat core.logAllRefUpdates core.loosecompression core.packedGitLimit core.packedGitWindowSize core.pager core.preferSymlinkRefs core.preloadindex core.quotepath core.repositoryFormatVersion core.safecrlf core.sharedRepository core.symlinks core.trustctime core.warnAmbiguousRefs core.whitespace core.worktree diff.autorefreshindex diff.external diff.mnemonicprefix diff.renameLimit diff.renameLimit. diff.renames diff.suppressBlankEmpty diff.tool diff.wordRegex difftool. difftool.prompt fetch.unpackLimit format.attach format.cc format.headers format.numbered format.pretty format.signature format.signoff format.subjectprefix format.suffix format.thread gc.aggressiveWindow gc.auto gc.autopacklimit gc.packrefs gc.pruneexpire gc.reflogexpire gc.reflogexpireunreachable gc.rerereresolved gc.rerereunresolved gitcvs.allbinary gitcvs.commitmsgannotation gitcvs.dbTableNamePrefix gitcvs.dbdriver gitcvs.dbname gitcvs.dbpass gitcvs.dbuser gitcvs.enabled gitcvs.logfile gitcvs.usecrlfattr guitool. gui.blamehistoryctx gui.commitmsgwidth gui.copyblamethreshold gui.diffcontext gui.encoding gui.fastcopyblame gui.matchtrackingbranch gui.newbranchtemplate gui.pruneduringfetch gui.spellingdictionary gui.trustmtime help.autocorrect help.browser help.format http.lowSpeedLimit http.lowSpeedTime http.maxRequests http.noEPSV http.proxy http.sslCAInfo http.sslCAPath http.sslCert http.sslKey http.sslVerify i18n.commitEncoding i18n.logOutputEncoding imap.folder imap.host imap.pass imap.port imap.preformattedHTML imap.sslverify imap.tunnel imap.user instaweb.browser instaweb.httpd instaweb.local instaweb.modulepath instaweb.port interactive.singlekey log.date log.showroot mailmap.file man. man.viewer merge.conflictstyle merge.log merge.renameLimit merge.stat merge.tool merge.verbosity mergetool. mergetool.keepBackup mergetool.prompt pack.compression pack.deltaCacheLimit pack.deltaCacheSize pack.depth pack.indexVersion pack.packSizeLimit pack.threads pack.window pack.windowMemory pager. pull.octopus pull.twohead push.default rebase.stat receive.denyCurrentBranch receive.denyDeletes receive.denyNonFastForwards receive.fsckObjects receive.unpackLimit repack.usedeltabaseoffset rerere.autoupdate rerere.enabled sendemail.aliasesfile sendemail.aliasesfiletype sendemail.bcc sendemail.cc sendemail.cccmd sendemail.chainreplyto sendemail.confirm sendemail.envelopesender sendemail.multiedit sendemail.signedoffbycc sendemail.smtpencryption sendemail.smtppass sendemail.smtpserver sendemail.smtpserverport sendemail.smtpuser sendemail.suppresscc sendemail.suppressfrom sendemail.thread sendemail.to sendemail.validate showbranch.default status.relativePaths status.showUntrackedFiles tar.umask transfer.unpackLimit url. user.email user.name user.signingkey web.browser branch. remote. " } _git_remote () { local subcommands="add rename rm show prune update set-head" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" return fi case "$subcommand" in rename|rm|show|prune) __gitcomp "$(__git_remotes)" ;; update) local i c='' IFS=$'\n' for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do i="${i#remotes.}" c="$c ${i/ */}" done __gitcomp "$c" ;; *) COMPREPLY=() ;; esac } _git_replace () { __gitcomp "$(__git_refs)" } _git_reset () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--merge --mixed --hard --soft --patch" return ;; esac __gitcomp "$(__git_refs)" } _git_revert () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--edit --mainline --no-edit --no-commit --signoff" return ;; esac __gitcomp "$(__git_refs)" } _git_rm () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--cached --dry-run --ignore-unmatch --quiet" return ;; esac COMPREPLY=() } _git_shortlog () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " $__git_log_common_options $__git_log_shortlog_options --numbered --summary " return ;; esac __git_complete_revlist } _git_show () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --pretty=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; --format=*) __gitcomp "$__git_log_pretty_formats " "" "${cur##--format=}" return ;; --*) __gitcomp "--pretty= --format= --abbrev-commit --oneline $__git_diff_common_options " return ;; esac __git_complete_file } _git_show_branch () { local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp " --all --remotes --topo-order --current --more= --list --independent --merge-base --no-name --color --no-color --sha1-name --sparse --topics --reflog " return ;; esac __git_complete_revlist } _git_stash () { local cur="${COMP_WORDS[COMP_CWORD]}" local save_opts='--keep-index --no-keep-index --quiet --patch' local subcommands='save list show apply clear drop pop create branch' local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then case "$cur" in --*) __gitcomp "$save_opts" ;; *) if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then __gitcomp "$subcommands" else COMPREPLY=() fi ;; esac else case "$subcommand,$cur" in save,--*) __gitcomp "$save_opts" ;; apply,--*|pop,--*) __gitcomp "--index --quiet" ;; show,--*|drop,--*|branch,--*) COMPREPLY=() ;; show,*|apply,*|drop,*|pop,*|branch,*) __gitcomp "$(git --git-dir="$(__gitdir)" stash list \ | sed -n -e 's/:.*//p')" ;; *) COMPREPLY=() ;; esac fi } _git_submodule () { __git_has_doubledash && return local subcommands="add status init update summary foreach sync" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) __gitcomp "--quiet --cached" ;; *) __gitcomp "$subcommands" ;; esac return fi } _git_svn () { local subcommands=" init fetch clone rebase dcommit log find-rev set-tree commit-diff info create-ignore propget proplist show-ignore show-externals branch tag blame migrate mkdirs reset gc " local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" else local remote_opts="--username= --config-dir= --no-auth-cache" local fc_opts=" --follow-parent --authors-file= --repack= --no-metadata --use-svm-props --use-svnsync-props --log-window-size= --no-checkout --quiet --repack-flags --use-log-author --localtime --ignore-paths= $remote_opts " local init_opts=" --template= --shared= --trunk= --tags= --branches= --stdlayout --minimize-url --no-metadata --use-svm-props --use-svnsync-props --rewrite-root= --prefix= --use-log-author --add-author-from $remote_opts " local cmt_opts=" --edit --rmdir --find-copies-harder --copy-similarity= " local cur="${COMP_WORDS[COMP_CWORD]}" case "$subcommand,$cur" in fetch,--*) __gitcomp "--revision= --fetch-all $fc_opts" ;; clone,--*) __gitcomp "--revision= $fc_opts $init_opts" ;; init,--*) __gitcomp "$init_opts" ;; dcommit,--*) __gitcomp " --merge --strategy= --verbose --dry-run --fetch-all --no-rebase --commit-url --revision $cmt_opts $fc_opts " ;; set-tree,--*) __gitcomp "--stdin $cmt_opts $fc_opts" ;; create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\ show-externals,--*|mkdirs,--*) __gitcomp "--revision=" ;; log,--*) __gitcomp " --limit= --revision= --verbose --incremental --oneline --show-commit --non-recursive --authors-file= --color " ;; rebase,--*) __gitcomp " --merge --verbose --strategy= --local --fetch-all --dry-run $fc_opts " ;; commit-diff,--*) __gitcomp "--message= --file= --revision= $cmt_opts" ;; info,--*) __gitcomp "--url" ;; branch,--*) __gitcomp "--dry-run --message --tag" ;; tag,--*) __gitcomp "--dry-run --message" ;; blame,--*) __gitcomp "--git-format" ;; migrate,--*) __gitcomp " --config-dir= --ignore-paths= --minimize --no-auth-cache --username= " ;; reset,--*) __gitcomp "--revision= --parent" ;; *) COMPREPLY=() ;; esac fi } _git_tag () { local i c=1 f=0 while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in -d|-v) __gitcomp "$(__git_tags)" return ;; -f) f=1 ;; esac c=$((++c)) done case "${COMP_WORDS[COMP_CWORD-1]}" in -m|-F) COMPREPLY=() ;; -*|tag) if [ $f = 1 ]; then __gitcomp "$(__git_tags)" else COMPREPLY=() fi ;; *) __gitcomp "$(__git_refs)" ;; esac } _git_whatchanged () { _git_log } _git () { local i c=1 command __git_dir while [ $c -lt $COMP_CWORD ]; do i="${COMP_WORDS[c]}" case "$i" in --git-dir=*) __git_dir="${i#--git-dir=}" ;; --bare) __git_dir="." ;; --version|-p|--paginate) ;; --help) command="help"; break ;; *) command="$i"; break ;; esac c=$((++c)) done if [ -z "$command" ]; then case "${COMP_WORDS[COMP_CWORD]}" in --*) __gitcomp " --paginate --no-pager --git-dir= --bare --version --exec-path --html-path --work-tree= --help " ;; *) __git_compute_porcelain_commands __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;; esac return fi local completion_func="_git_${command//-/_}" declare -F $completion_func >/dev/null && $completion_func && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then completion_func="_git_${expansion//-/_}" declare -F $completion_func >/dev/null && $completion_func fi } _gitk () { __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(__gitdir)" local merge="" if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi case "$cur" in --*) __gitcomp " $__git_log_common_options $__git_log_gitk_options $merge " return ;; esac __git_complete_revlist } complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \ || complete -o default -o nospace -F _git git complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \ || complete -o default -o nospace -F _gitk gitk # The following are necessary only for Cygwin, and only are needed # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ || complete -o default -o nospace -F _git git.exe fi
mattshoe / KernlKernl is a Kotlin library built to simplify the majority of data management scenarios. Kernl uses a flexible and declarative approach to defining data management strategies. Kernl gives you granular control over all aspects of caching, from in-memory network caching to offline backups to database persistence to Key-Value storage.
shipclojure / Re Frame QueryDeclarative data fetching and caching for re-frame inspired by tanstack query and redux toolkit query
zloeber / Terraform Cicd ImageDocker image for terraform provisioning that supports provider plugin caching and declarative binary installation via mise.
Nate158s / Digital Marketing # Routing with EdgeJS https://github.com/Nate158s The `{{ PACKAGE_NAME }}/core` package provides a JavaScript API for controlling routing and caching from your code base rather than a CDN web portal. Using this _{{ EDGEJS_LABEL }}_ approach allows this vital routing logic to be properly tested, reviewed, and version controlled, just like the rest of your application code. Using the Router, you can: - Proxy requests to upstream sites - Send redirects from the network edge - Render responses on the server using Next.js, Nuxt.js, Angular, or any other framework that supports server side rendering. - Alter request and response headers - Send synthetic responses - Configure multiple destinations for split testing ## Configuration To define routes for {{ PRODUCT_NAME }}, create a `routes.js` file in the root of your project. You can override the default path to the router by setting the `routes` key in `{{ CONFIG_FILE }}`. The `routes.js` file should export an instance of `{{ PACKAGE_NAME }}/core/router/Router`: ```js // routes.js const { Router } = require('{{ PACKAGE_NAME }}/core/router') module.exports = new Router() ``` ## Declare Routes Declare routes using the method corresponding to the HTTP method you want to match. ```js // routes.js const { Router } = require('{{ PACKAGE_NAME }}/core/router') module.exports = new Router().get('/some-path', ({ cache, proxy }) => { // handle the request here }) ``` All HTTP methods are available: - get - put - post - patch - delete - head To match all methods, use `match`: ```js // routes.js const { Router } = require('{{ PACKAGE_NAME }}/core/router') module.exports = new Router().match('/some-path', ({ cache, proxy }) => { // handle the request here }) ``` ## Route Execution When {{ PRODUCT_NAME }} receives a request, it executes **each route that matches the request** in the order in which they are declared until one sends a response. The following methods return a response: - [appShell](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#appshell) - [compute](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#compute) - [proxy](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#proxy) - [redirect](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#redirect) - [send](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#send) - [serveStatic](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#servestatic) - [serviceWorker](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#serviceworker) - [stream](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#stream) - [use](/docs/api/core/classes/_router_responsewriter_.responsewriter.html#compute) Multiple routes can therefore be executed for a given request. A common pattern is to add caching with one route and render the response with a later one using middleware. In the following example we cache then render a response with Next.js: ```js const { Router } = require('{{ PACKAGE_NAME }}/core/router') const { nextRoutes } = require('{{ PACKAGE_NAME }}/next') // In this example a request to /products/1 will be cached by the first route, then served by the `nextRoutes` middleware new Router() .get('/products/:id', ({ cache }) => { cache({ edge: { maxAgeSeconds: 60 * 60, staleWhileRevalidateSeconds: 60 * 60 }, }) }) .use(nextRoutes) ``` ### Alter Requests and Responses {{ PRODUCT_NAME }} offers APIs to manipulate request and response headers and cookies. The APIs are: | Operation | Request | Upstream Response | Response sent to Browser | | ------------- | --------------------- | ------------------------------ | ------------------------ | | Set header | `setRequestHeader` | `setUpstreamResponseHeader` | `setResponseHeader` | | Add cookie | `*` | `addUpstreamResponseCookie` | `addResponseCookie` | | Update header | `updateRequestHeader` | `updateUpstreamResponseHeader` | `updateResponseHeader` | | Update cookie | `*` | `updateUpstreamResponseCookie` | `updateResponseCookie` | | Remove header | `removeRequestHeader` | `removeUpstreamResponseHeader` | `removeResponseHeader` | | Remove cookie | `*` | `removeUpstreamResponseCookie` | `removeResponseCookie` | `*` Adding, updating, or removing a request cookie can be achieved with `updateRequestHeader` applied to `cookie` header. You can find detailed descriptions of these APIs in the `{{ PACKAGE_NAME }}/core` [documentation](/docs/api/core/classes/_router_responsewriter_.responsewriter.html). #### Embedded Values You can inject values from the request or response into headers or cookies as template literals using the `${value}` format. For example: `setResponseHeader('original-request-path', '${path}')` would add an `original-request-path` response header whose value is the request path. | Value | Embedded value | Description | | --------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | HTTP method | `${method}` | The value of the HTTP method used for the request (e.g. `GET`) | | URL | `${url}` | The complete URL path including any query strings (e.g. `/search?query=docs`). Protocol, hostname, and port are not included. | | Path | `${path}` | The URL path excluding any query strings (e.g. `/search`) | | Query string | `${query:<name>}` | The value of the `<name>` query string or empty if not available. | | Request header | `${req:<name>}` | The value of the `<name>` request header or empty if not available. | | Request cookie | `${req:cookie:<name>}` | The value of the `<name>` cookie in `cookie` request header or empty if not available. | | Response header | `${res:<name>}` | The value of the `<name>` response header or empty if not available. | ## Route Pattern Syntax The syntax for route paths is provided by [path-to-regexp](https://github.com/pillarjs/path-to-regexp#path-to-regexp), which is the same library used by [Express](https://expressjs.com/). ### Named Parameters Named parameters are defined by prefixing a colon to the parameter name (`:foo`). ```js new Router().get('/:foo/:bar', res => { /* ... */ }) ``` **Please note:** Parameter names must use "word characters" (`[A-Za-z0-9_]`). #### Custom Matching Parameters Parameters can have a custom regexp, which overrides the default match (`[^/]+`). For example, you can match digits or names in a path: ```js new Router().get('/icon-:foo(\\d+).png', res => { /* ... */ }) ``` **Tip:** Backslashes need to be escaped with another backslash in JavaScript strings. #### Custom Prefix and Suffix Parameters can be wrapped in `{}` to create custom prefixes or suffixes for your segment: ```js new Router().get('/:attr1?{-:attr2}?{-:attr3}?', res => { /* ... */ }) ``` ### Unnamed Parameters It is possible to write an unnamed parameter that only consists of a regexp. It works the same the named parameter, except it will be numerically indexed: ```js new Router().get('/:foo/(.*)', res => { /* ... */ }) ``` ### Modifiers Modifiers must be placed after the parameter (e.g. `/:foo?`, `/(test)?`, `/:foo(test)?`, or `{-:foo(test)}?`). #### Optional Parameters can be suffixed with a question mark (`?`) to make the parameter optional. ```js new Router().get('/:foo/:bar?', res => { /* ... */ }) ``` **Tip:** The prefix is also optional, escape the prefix `\/` to make it required. #### Zero or More Parameters can be suffixed with an asterisk (`*`) to denote zero or more parameter matches. ```js new Router().get('/:foo*', res => { /* res.params.foo will be an array */ }) ``` The captured parameter value will be provided as an array. #### One or More Parameters can be suffixed with a plus sign (`+`) to denote one or more parameter matches. ```js new Router().get('/:foo+', res => { /* res.params.foo will be an array */ }) ``` The captured parameter value will be provided as an array. ## Matching Method, Query Parameters, Cookies, and Headers Match can either take a URL path, or an object which allows you to match based on method, query parameters, cookies, or request headers: ```js router.match( { path: '/some-path', // value is route-pattern syntax method: /GET|POST/i, // value is a regular expression cookies: { currency: /^(usd)$/i }, // keys are cookie names, values are regular expressions headers: { 'x-moov-device': /^desktop$/i }, // keys are header names, values are regular expressions query: { page: /^(1|2|3)$/ }, // keys are query parameter names, values are regular expressions }, () => {}, ) ``` ## Body Matching for POST requests You can also match HTTP `POST` requests based on their request body content as in the following example: ```js router.match( { body: { parse: 'json', criteria: { operationName: 'GetProducts' } }, // the body content will parsed as JSON and the parsed JSON matched against the presence of the criteria properties (in this case a GraphQL operation named 'GetProducts') }, () => {}, ) ``` Currently the only body content supported is JSON. Body content is parsed as JSON and is matched against the presence of the fields specified in the `criteria` field. The [_POST Body Matching Criteria_](#section_post_body_matching_criteria) section below contains examples of using the `criteria` field. Body matching can be combined with other match parameters such as headers and cookies. For example, ```js router.match( { // Only matches GetProducts operations to the /graphql endpoint // for logged in users path: '/graphql', cookies: { loginStatus: /^(loggedIn)$/i }, // loggedin users body: { parse: 'json', criteria: { operationName: 'GetProducts' } }, }, () => {}, ) ``` ### Caching & POST Body Matching When body matching is combined with `cache` in a route, **the HTTP request body will automatically be used as the cache key.** For example, the code below will cache GraphQL `GetProducts` queries using the entire request body as the cache key: ```js router.match( { body: { parse: 'json', criteria: { operationName: 'GetProducts' } }, }, ({ cache }) => { cache({ edge: { maxAgeSeconds: 60 * 60, staleWhileRevalidateSeconds: 60 * 60 * 24, // this way stale items can still be prefetched }, }) }, ) ``` You can still add additional parameters to the cache key using the normal {{ EDGEJS_LABEL }} `key` property. For example, the code below will cache GraphQL `GetProducts` queries separately for each user based on their userID cookie _and_ the HTTP body of the request. ```js router.match( { body: { parse: 'json', criteria: { operationName: 'GetProducts' } }, }, ({ cache }) => { cache({ edge: { maxAgeSeconds: 60 * 60, staleWhileRevalidateSeconds: 60 * 60 * 24, // this way stale items can still be prefetched }, key: new CustomCacheKey().addCookie('userID'), // Split cache by userID }) }, ) ``` ### POST Body Matching Criteria The `criteria` property can be a string or regular expression. For example, the router below, ```js router.match( { body: { parse: 'json', criteria: { foo: 'bar' } }, }, () => {}, ) ``` would match an HTTP POST request body containing: ```js { "foo": "bar", "bar": "foo" } ``` ### Regular Expression Criteria Regular expressions can also be used as `criteria`. For example, ```js router.match( { body: { parse: 'json', criteria: { operationName: /^Get/ } }, }, () => {}, ) ``` would match an HTTP POST body containing: ```js { "operationName": "GetShops", "query": "...", "variables": {} } ``` ### Nested JSON Criteria You can also use a nested object to match a field at a specific location in the JSON. For example, ```js router.match( { body: { parse: 'json', criteria: { operation: { name: 'GetShops', }, }, }, }, () => {}, ) ``` would match an HTTP POST body containing: ```js { "operation": { "name": "GetShops", "query": "..." } } ``` ## GraphQL Queries The {{ EDGEJS_LABEL }} router provides a `graphqlOperation` method for matching GraphQL. ```js router.graphqlOperation('GetProducts', res => { /* Handle the POST for the GetProducts query specifically */ }) ``` By default, the `graphqlOperation` assumes your GraphQL endpoint is at `/graphql`. You can alter this behavior by using the `path` property as shown below: ```js router.graphqlOperation({ path: '/api/graphql', name: 'GetProducts' }, res => { /* Handle the POST for the GetProducts query specifically */ }) ``` Note that when the `graphqlOperation` function is used, the HTTP request body will automatically be included in the cache key. The `graphqlOperation` function is provided to simplify matching of common GraphQL scenarios. For complex GraphQL matching (such as authenticated data), you can use the generic [_Body Matching for POST requests_](#section_body_matching_for_post_requests) feature. See the guide on [Implementing GraphQL Routing](/guides/graphql) in your project. ## Request Handling The second argument to routes is a function that receives a `ResponseWriter` and uses it to send a response. Using `ResponseWriter` you can: - Proxy a backend configured in `{{ CONFIG_FILE }}` - Serve a static file - Send a redirect - Send a synthetic response - Cache the response at edge and in the browser - Manipulate request and response headers [See the API Docs for Response Writer](/docs/__version__/api/core/classes/_router_responsewriter_.responsewriter.html) ## Full Example This example shows typical usage of `{{ PACKAGE_NAME }}/core`, including serving a service worker, next.js routes (vanity and conventional routes), and falling back to a legacy backend. ```js // routes.js const { Router } = require('{{ PACKAGE_NAME }}/core/router') module.exports = new Router() .get('/service-worker.js', ({ serviceWorker }) => { // serve the service worker built by webpack serviceWorker('dist/service-worker.js') }) .get('/p/:productId', ({ cache }) => { // cache products for one hour at edge and using the service worker cache({ edge: { maxAgeSeconds: 60 * 60, staleWhileRevalidateSeconds: 60 * 60, }, browser: { maxAgeSeconds: 0, serviceWorkerSeconds: 60 * 60, }, }) proxy('origin') }) .fallback(({ proxy }) => { // serve all unmatched URLs from the origin backend configured in {{ CONFIG_FILE }} proxy('origin') }) ``` ## Errors Handling You can use the router's `catch` method to return specific content when the request results in an error status (For example, a 500). Using `catch`, you can also alter the `statusCode` and `response` on the edge before issuing a response to the user. ```js router.catch(number | Regexp, (routeHandler: Function)) ``` ### Examples To issue a custom error page when the origin returns a 500: ```js // routes.js const { Router } = require('{{ PACKAGE_NAME }}/core/router') module.exports = new Router() // Example route .get('/failing-route', ({ proxy }) => { proxy('broken-origin') }) // So let's assume that backend "broken-origin" returns 500, so instead // of rendering the broken-origin response we can alter that by specifing .catch .catch(500, ({ serveStatic }) => { serveStatic('static/broken-origin-500-page.html', { statusCode: 502, }) }) ``` The `.catch` method allows the edge router to render a response based on the result preceeding routes. So in the example above whenever we receive a 500 we respond with `broken-origin-500-page.html` from the application's `static` directory and change the status code to 502. - Your catch callback is provided a [ResponseWriter](/docs/api/core/classes/_router_responsewriter_.responsewriter.html) instance. You can use any ResponseWriter method except `proxy` inside `.catch`. - We highly recommend keeping `catch` routes simple. Serve responses using `serveStatic` instead of `send` to minimize the size of the edge bundle. ## Environment Edge Redirects In addition to sending redirects at the edge within the router configuration, this can also be configured at the environment level within the Layer0 Developer Console. Under _<Your Environment> → Configuration_, click _Edit_ to draft a new configuration. Scroll down to the _Redirects_ section:  Click _Add A Redirect_ to configure the path or host you wish to redirect to:  **Note:** you will need to activate and redeploy your site for this change to take effect.
https-github-com-Rama24 / Peretesan.This XML file does not appear to have any style information associated with it. The document tree is shown below. <xsd:schema xmlns="http://www.springframework.org/schema/mvc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" targetNamespace="http://www.springframework.org/schema/mvc" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="https://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/> <xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="https://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/> <xsd:element name="annotation-driven"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <![CDATA[ Configures the annotation-driven Spring MVC Controller programming model. Note that this tag works in Web MVC only, not in Portlet MVC! See org.springframework.web.servlet.config.annotation.EnableWebMvc javadoc for details on code-based alternatives to enabling annotation-driven Spring MVC support. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:all minOccurs="0"> <xsd:element name="path-matching" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configures the path matching part of the Spring MVC Controller programming model. Like annotation-driven, code-based alternatives are also documented in EnableWebMvc javadoc. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="suffix-pattern" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to use suffix pattern match (".*") when matching patterns to requests. If enabled a method mapped to "/users" also matches to "/users.*". The default value is true. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="trailing-slash" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to match to URLs irrespective of the presence of a trailing slash. If enabled a method mapped to "/users" also matches to "/users/". The default value is true. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="registered-suffixes-only" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether suffix pattern matching should work only against path extensions explicitly registered when you configure content negotiation. This is generally recommended to reduce ambiguity and to avoid issues such as when a "." appears in the path for other reasons. The default value is false. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="path-helper" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The bean name of the UrlPathHelper to use for resolution of lookup paths. Use this to override the default UrlPathHelper with a custom subclass, or to share common UrlPathHelper settings across multiple HandlerMappings and MethodNameResolvers. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="path-matcher" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The bean name of the PathMatcher implementation to use for matching URL paths against registered URL patterns. Default is AntPathMatcher. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="message-converters" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configures one or more HttpMessageConverter types to use for converting @RequestBody method parameters and @ResponseBody method return values. Using this configuration element is optional. HttpMessageConverter registrations provided here will take precedence over HttpMessageConverter types registered by default. Also see the register-defaults attribute if you want to turn off default registrations entirely. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:choice maxOccurs="unbounded"> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation> <![CDATA[ An HttpMessageConverter bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation> <![CDATA[ A reference to an HttpMessageConverter bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:sequence> <xsd:attribute name="register-defaults" type="xsd:boolean" default="true"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether or not default HttpMessageConverter registrations should be added in addition to the ones provided within this element. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="argument-resolvers" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configures HandlerMethodArgumentResolver types to support custom controller method argument types. Using this option does not override the built-in support for resolving handler method arguments. To customize the built-in support for argument resolution configure RequestMappingHandlerAdapter directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:choice minOccurs="1" maxOccurs="unbounded"> <xsd:element ref="beans:bean" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ The HandlerMethodArgumentResolver (or WebArgumentResolver for backwards compatibility) bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ A reference to a HandlerMethodArgumentResolver bean definition. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.web.method.support.HandlerMethodArgumentResolver"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="return-value-handlers" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configures HandlerMethodReturnValueHandler types to support custom controller method return value handling. Using this option does not override the built-in support for handling return values. To customize the built-in support for handling return values configure RequestMappingHandlerAdapter directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:choice minOccurs="1" maxOccurs="unbounded"> <xsd:element ref="beans:bean" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ The HandlerMethodReturnValueHandler bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ A reference to a HandlerMethodReturnValueHandler bean definition. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.web.method.support.HandlerMethodReturnValueHandler"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:element name="async-support" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure options for asynchronous request processing. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:all minOccurs="0"> <xsd:element name="callable-interceptors" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ The ordered set of interceptors that intercept the lifecycle of concurrently executed requests, which start after a controller returns a java.util.concurrent.Callable. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ Registers a CallableProcessingInterceptor. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="deferred-result-interceptors" minOccurs="0"> <xsd:annotation> <xsd:documentation> <![CDATA[ The ordered set of interceptors that intercept the lifecycle of concurrently executed requests, which start after a controller returns a DeferredResult. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ Registers a DeferredResultProcessingInterceptor. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:all> <xsd:attribute name="task-executor" type="xsd:string"> <xsd:annotation> <xsd:documentation source="java:org.springframework.core.task.AsyncTaskExecutor"> <![CDATA[ The bean name of a default AsyncTaskExecutor to use when a controller method returns a {@link Callable}. Controller methods can override this default on a per-request basis by returning an AsyncTask. By default, a SimpleAsyncTaskExecutor is used which does not re-use threads and is not recommended for production. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.core.task.AsyncTaskExecutor"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="default-timeout" type="xsd:long"> <xsd:annotation> <xsd:documentation> <![CDATA[ Specify the amount of time, in milliseconds, before asynchronous request handling times out. In Servlet 3, the timeout begins after the main request processing thread has exited and ends when the request is dispatched again for further processing of the concurrently produced result. If this value is not set, the default timeout of the underlying implementation is used, e.g. 10 seconds on Tomcat with Servlet 3. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:all> <xsd:attribute name="conversion-service" type="xsd:string"> <xsd:annotation> <xsd:documentation source="java:org.springframework.core.convert.ConversionService"> <![CDATA[ The bean name of the ConversionService that is to be used for type conversion during field binding. This attribute is not required, and only needs to be specified if custom converters need to be configured. If not specified, a default FormattingConversionService is registered with converters to/from common value types. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.core.convert.ConversionService"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="validator" type="xsd:string"> <xsd:annotation> <xsd:documentation source="java:org.springframework.validation.Validator"> <![CDATA[ The bean name of the Validator that is to be used to validate Controller model objects. This attribute is not required, and only needs to be specified if a custom Validator needs to be configured. If not specified, JSR-303 validation will be installed if a JSR-303 provider is present on the classpath. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.validation.Validator"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="content-negotiation-manager" type="xsd:string"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.accept.ContentNegotiationManager"> <![CDATA[ The bean name of a ContentNegotiationManager that is to be used to determine requested media types. If not specified, a default ContentNegotiationManager is configured that checks the request path extension first and the "Accept" header second where path extensions such as ".json", ".xml", ".atom", and ".rss" are recognized if Jackson, JAXB2, or the Rome libraries are available. As a fallback option, the path extension is also used to perform a lookup through the ServletContext and the Java Activation Framework (if available). ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.web.accept.ContentNegotiationManager"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="message-codes-resolver" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The bean name of a MessageCodesResolver to use to build message codes from data binding and validation error codes. This attribute is not required. If not specified the DefaultMessageCodesResolver is used. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.validation.MessageCodesResolver"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="enable-matrix-variables" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Matrix variables can appear in any path segment, each matrix variable separated with a ";" (semicolon). For example "/cars;color=red;year=2012". By default, they're removed from the URL. If this property is set to true, matrix variables are not removed from the URL, and the request mapping pattern must use URI variable in path segments where matrix variables are expected. For example "/{cars}". Matrix variables can then be injected into a controller method with @MatrixVariable. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="ignore-default-model-on-redirect" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ By default, the content of the "default" model is used both during rendering and redirect scenarios. Alternatively a controller method can declare a RedirectAttributes argument and use it to provide attributes for a redirect. Setting this flag to true ensures the "default" model is never used in a redirect scenario even if a RedirectAttributes argument is not declared. Setting it to false means the "default" model may be used in a redirect if the controller method doesn't declare a RedirectAttributes argument. The default setting is false but new applications should consider setting it to true. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:complexType name="content-version-strategy"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ContentVersionStrategy"> <![CDATA[ A VersionStrategy that calculates an Hex MD5 hashes from the content of the resource and appends it to the file name, e.g. "styles/main-e36d2e05253c6c7085a91522ce43a0b4.css". ]]> </xsd:documentation> </xsd:annotation> <xsd:attribute name="patterns" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="fixed-version-strategy"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.FixedVersionStrategy"> <![CDATA[ A VersionStrategy that relies on a fixed version applied as a request path prefix, e.g. reduced SHA, version name, release date, etc. ]]> </xsd:documentation> </xsd:annotation> <xsd:attribute name="version" type="xsd:string" use="required"/> <xsd:attribute name="patterns" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="resource-version-strategy"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.VersionStrategy"> <![CDATA[ A strategy for extracting and embedding a resource version in its URL path. ]]> </xsd:documentation> </xsd:annotation> <xsd:choice minOccurs="1" maxOccurs="1"> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.VersionStrategy"> <![CDATA[ A VersionStrategy bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.VersionStrategy"> <![CDATA[ A reference to a VersionStrategy bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> <xsd:attribute name="patterns" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="version-resolver"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.VersionResourceResolver"> <![CDATA[ Resolves request paths containing a version string that can be used as part of an HTTP caching strategy in which a resource is cached with a far future date (e.g. 1 year) and cached until the version, and therefore the URL, is changed. ]]> </xsd:documentation> </xsd:annotation> <xsd:choice maxOccurs="unbounded"> <xsd:element type="content-version-strategy" name="content-version-strategy"/> <xsd:element type="fixed-version-strategy" name="fixed-version-strategy"/> <xsd:element type="resource-version-strategy" name="version-strategy"/> </xsd:choice> </xsd:complexType> <xsd:complexType name="resource-resolvers"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceResolver"> <![CDATA[ A list of ResourceResolver beans definition and references. A ResourceResolver provides mechanisms for resolving an incoming request to an actual Resource and for obtaining the public URL path that clients should use when requesting the resource. ]]> </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:choice maxOccurs="unbounded"> <xsd:element type="version-resolver" name="version-resolver"/> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceResolver"> <![CDATA[ A ResourceResolver bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceResolver"> <![CDATA[ A reference to a ResourceResolver bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> <xsd:complexType name="resource-transformers"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer"> <![CDATA[ A list of ResourceTransformer beans definition and references. A ResourceTransformer provides mechanisms for transforming the content of a resource. ]]> </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:choice maxOccurs="unbounded"> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer"> <![CDATA[ A ResourceTransformer bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer"> <![CDATA[ A reference to a ResourceTransformer bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> <xsd:complexType name="resource-chain"> <xsd:annotation> <xsd:documentation source="org.springframework.web.servlet.config.annotation.ResourceChainRegistration"> <![CDATA[ Assists with the registration of resource resolvers and transformers. Unless set to "false", the auto-registration adds default Resolvers (a PathResourceResolver) and Transformers (CssLinkResourceTransformer, if a VersionResourceResolver has been manually registered). The resource-cache attribute sets whether to cache the result of resource resolution/transformation; setting this to "true" is recommended for production (and "false" for development). A custom Cache can be configured if a CacheManager is provided as a bean reference in the "cache-manager" attribute, and the cache name provided in the "cache-name" attribute. ]]> </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="resolvers" type="resource-resolvers" minOccurs="0" maxOccurs="1"/> <xsd:element name="transformers" type="resource-transformers" minOccurs="0" maxOccurs="1"/> </xsd:sequence> <xsd:attribute name="resource-cache" type="xsd:boolean" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether the resource chain should cache resource resolution. Note that the resource content itself won't be cached, but rather Resource instances. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="auto-registration" type="xsd:boolean" default="true" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to register automatically ResourceResolvers and ResourceTransformers. Setting this property to "false" means that it gives developers full control over the registration process. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-manager" type="xsd:string" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ The name of the Cache Manager to cache resource resolution. By default, a ConcurrentCacheMap will be used. Since Resources aren't serializable and can be dependent on the application host, one should not use a distributed cache but rather an in-memory cache. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-name" type="xsd:string" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ The cache name to use in the configured cache manager. Will use "spring-resource-chain-cache" by default. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:complexType name="cache-control"> <xsd:annotation> <xsd:documentation source="org.springframework.web.cache.CacheControl"> <![CDATA[ Generates "Cache-Control" HTTP response headers. ]]> </xsd:documentation> </xsd:annotation> <xsd:attribute name="must-revalidate" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "must-revalidate" directive in the Cache-Control header. This indicates that caches should revalidate the cached response when it's become stale. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="no-cache" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "no-cache" directive in the Cache-Control header. This indicates that caches should always revalidate cached response with the server. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="no-store" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "no-store" directive in the Cache-Control header. This indicates that caches should never cache the response. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="no-transform" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "no-transform" directive in the Cache-Control header. This indicates that caches should never transform (i.e. compress, optimize) the response content. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-public" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "public" directive in the Cache-Control header. This indicates that any cache MAY store the response. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-private" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "private" directive in the Cache-Control header. This indicates that the response is intended for a single user and may not be stored by shared caches. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="proxy-revalidate" type="xsd:boolean" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "proxy-revalidate" directive in the Cache-Control header. This directive has the same meaning as the "must-revalidate" directive, except it only applies to shared caches. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="max-age" type="xsd:int" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "max-age" directive in the Cache-Control header. This indicates that the response should be cached for the given number of seconds. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="s-maxage" type="xsd:int" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "s-maxage" directive in the Cache-Control header. This directive has the same meaning as the "max-age" directive, except it only applies to shared caches. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="stale-while-revalidate" type="xsd:int" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "stale-while-revalidate" directive in the Cache-Control header. This indicates that caches may serve the response after it becomes stale up to the given number of seconds. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="stale-if-error" type="xsd:int" use="optional"> <xsd:annotation> <xsd:documentation> <![CDATA[ Adds a "stale-if-error" directive in the Cache-Control header. When an error is encountered, a cached stale response may be used for the given number of seconds. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:element name="resources"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.resource.ResourceHttpRequestHandler"> <![CDATA[ Configures a handler for serving static resources such as images, js, and, css files with cache headers optimized for efficient loading in a web browser. Allows resources to be served out of any path that is reachable via Spring's Resource handling. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="cache-control" type="cache-control" minOccurs="0" maxOccurs="1"/> <xsd:element name="resource-chain" type="resource-chain" minOccurs="0" maxOccurs="1"/> </xsd:sequence> <xsd:attribute name="mapping" use="required" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The URL mapping pattern within the current Servlet context to use for serving resources from this handler, such as "/resources/**" ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="location" use="required" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The resource location from which to serve static content, specified at a Spring Resource pattern. Each location must point to a valid directory. Multiple locations may be specified as a comma-separated list, and the locations will be checked for a given resource in the order specified. For example, a value of "/, classpath:/META-INF/public-web-resources/" will allow resources to be served both from the web app root and from any JAR on the classpath that contains a /META-INF/public-web-resources/ directory, with resources in the web app root taking precedence. For URL-based resources (e.g. files, HTTP URLs, etc) this property supports a special prefix to indicate the charset associated with the URL so that relative paths appended to it can be encoded correctly, e.g. "[charset=Windows-31J]https://example.org/path". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-period" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Specifies the cache period for the resources served by this resource handler, in seconds. The default is to not send any cache headers but rather to rely on last-modified timestamps only. Set this to 0 in order to send cache headers that prevent caching, or to a positive number of seconds in order to send cache headers with the given max-age value. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="order" type="xsd:token"> <xsd:annotation> <xsd:documentation> <![CDATA[ Specifies the order of the HandlerMapping for the resource handler. The default order is Ordered.LOWEST_PRECEDENCE - 1. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="default-servlet-handler"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler"> <![CDATA[ Configures a handler for serving static resources by forwarding to the Servlet container's default Servlet. Use of this handler allows using a "/" mapping with the DispatcherServlet while still utilizing the Servlet container to serve static resources. This handler will forward all requests to the default Servlet. Therefore it is important that it remains last in the order of all other URL HandlerMappings. That will be the case if you use the "annotation-driven" element or alternatively if you are setting up your customized HandlerMapping instance be sure to set its "order" property to a value lower than that of the DefaultServletHttpRequestHandler, which is Integer.MAX_VALUE. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="default-servlet-name" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The name of the default Servlet to forward to for static resource requests. The handler will try to autodetect the container's default Servlet at startup time using a list of known names. If the default Servlet cannot be detected because of using an unknown container or because it has been manually configured, the servlet name must be set explicitly. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="interceptors"> <xsd:annotation> <xsd:documentation> <![CDATA[ The ordered set of interceptors that intercept HTTP Servlet Requests handled by Controllers. Interceptors allow requests to be pre/post processed before/after handling. Each interceptor must implement the org.springframework.web.servlet.HandlerInterceptor or org.springframework.web.context.request.WebRequestInterceptor interface. The interceptors in this set are automatically detected by every registered HandlerMapping. The URI paths each interceptor applies to are configurable. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:choice> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Registers an interceptor that intercepts every request regardless of its URI path.. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation> <![CDATA[ Registers an interceptor that intercepts every request regardless of its URI path.. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> <xsd:element name="interceptor"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.handler.MappedInterceptor"> <![CDATA[ Registers an interceptor that interceptors requests sent to one or more URI paths. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="mapping" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ A path into the application intercepted by this interceptor. Exact path mapping URIs (such as "/myPath") are supported as well as Ant-stype path patterns (such as /myPath/**). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="exclude-mapping" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ A path into the application that should not be intercepted by this interceptor. Exact path mapping URIs (such as "/admin") are supported as well as Ant-stype path patterns (such as /admin/**). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:choice> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation> <![CDATA[ The interceptor's bean definition. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation> <![CDATA[ A reference to an interceptor bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> <xsd:attribute name="path-matcher" type="xsd:string"> <xsd:annotation> <xsd:documentation source="java:org.springframework.util.PathMatcher"> <![CDATA[ The bean name of a PathMatcher implementation to use with nested interceptors. This is an optional, advanced property required only if using custom PathMatcher implementations that support mapping metadata other than the Ant path patterns supported by default. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:org.springframework.util.PathMatcher"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="view-controller"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.mvc.ParameterizableViewController"> <![CDATA[ Map a simple (logic-less) view controller to a specific URL path (or pattern) in order to render a response with a pre-configured status code and view. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The URL path (or pattern) the controller is mapped to. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="view-name" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the view name to return. Optional. If not specified, the view controller will return null as the view name in which case the configured RequestToViewNameTranslator will select the view name. The DefaultRequestToViewNameTranslator for example translates "/foo/bar" to "foo/bar". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="status-code" type="xsd:int"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the status code to set on the response. Optional. If not set the response status will be 200 (OK). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="redirect-view-controller"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.mvc.ParameterizableViewController"> <![CDATA[ Map a simple (logic-less) view controller to the given URL path (or pattern) in order to redirect to another URL. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The URL path (or pattern) the controller is mapped to. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="redirect-url" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ By default, the redirect URL is expected to be relative to the current ServletContext, i.e. as relative to the web application root. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="status-code" type="xsd:int"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the specific redirect 3xx status code to use. If not set, org.springframework.web.servlet.view.RedirectView will select MOVED_TEMPORARILY (302) by default. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="context-relative" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to interpret a given redirect URL that starts with a slash ("/") as relative to the current ServletContext, i.e. as relative to the web application root. The default is "true". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="keep-query-params" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to propagate the query parameters of the current request through to the target redirect URL. The default is "false". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="status-controller"> <xsd:annotation> <xsd:documentation source="java:org.springframework.web.servlet.mvc.ParameterizableViewController"> <![CDATA[ Map a simple (logic-less) controller to the given URL path (or pattern) in order to sets the response status to the given code without rendering a body. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The URL path (or pattern) the controller is mapped to. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="status-code" type="xsd:int" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The status code to set on the response. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:complexType name="contentNegotiationType"> <xsd:all> <xsd:element name="default-views" minOccurs="0"> <xsd:complexType> <xsd:sequence> <xsd:choice maxOccurs="unbounded"> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation> <![CDATA[ A bean definition for an org.springframework.web.servlet.View class. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation> <![CDATA[ A reference to a bean for an org.springframework.web.servlet.View class. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:all> <xsd:attribute name="use-not-acceptable" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Indicate whether a 406 Not Acceptable status code should be returned if no suitable view can be found. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:complexType name="urlViewResolverType"> <xsd:attribute name="prefix" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The prefix that gets prepended to view names when building a URL. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="suffix" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The suffix that gets appended to view names when building a URL. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-views" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Enable or disable thew caching of resolved views. Default is "true": caching is enabled. Disable this only for debugging and development. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="view-class" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The view class that should be used to create views. Configure this if you want to provide a custom View implementation, typically a ub-class of the expected View type. ]]> </xsd:documentation> <xsd:appinfo> <tool:annotation kind="ref"> <tool:expected-type type="java:java.lang.Class"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:attribute> <xsd:attribute name="view-names" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the view names (or name patterns) that can be handled by this view resolver. View names can contain simple wildcards such that 'my*', '*Report' and '*Repo*' will all match the view name 'myReport'. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> <xsd:element name="view-resolvers"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure a chain of ViewResolver instances to resolve view names returned from controllers into actual view instances to use for rendering. All registered resolvers are wrapped in a single (composite) ViewResolver with its order property set to 0 so that other external resolvers may be ordere ]]> <![CDATA[ d before or after it. When content negotiation is enabled the order property is set to highest priority instead with the ContentNegotiatingViewResolver encapsulating all other registered view resolver instances. That way the resolvers registered through the MVC namespace form self-encapsulated resolver chain. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:choice minOccurs="1" maxOccurs="unbounded"> <xsd:element name="content-negotiation" type="contentNegotiationType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Registers a ContentNegotiatingViewResolver with the list of all other registered ViewResolver instances used to set its "viewResolvers" property. See the javadoc of ContentNegotiatingViewResolver for more details. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="jsp" type="urlViewResolverType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register an InternalResourceViewResolver bean for JSP rendering. By default, "/WEB-INF/" is registered as a view name prefix and ".jsp" as a suffix. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="tiles" type="urlViewResolverType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a TilesViewResolver based on Tiles 3.x. To configure Tiles you must also add a top-level <mvc:tiles-configurer> element or declare a TilesConfigurer bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="freemarker" type="urlViewResolverType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a FreeMarkerViewResolver. By default, ".ftl" is configured as a view name suffix. To configure FreeMarker you must also add a top-level <mvc:freemarker-configurer> element or declare a FreeMarkerConfigurer bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="groovy" type="urlViewResolverType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a GroovyMarkupViewResolver. By default, ".tpl" is configured as a view name suffix. To configure the Groovy markup template engine you must also add a top-level <mvc:groovy-configurer> element or declare a GroovyMarkupConfigurer bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="script-template" type="urlViewResolverType"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a ScriptTemplateViewResolver. To configure the Script engine you must also add a top-level <mvc:script-template-configurer> element or declare a ScriptTemplateConfigurer bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="bean-name" maxOccurs="1"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a BeanNameViewResolver bean. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:bean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a ViewResolver as a direct bean declaration. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element ref="beans:ref"> <xsd:annotation> <xsd:documentation> <![CDATA[ Register a ViewResolver through references to an existing bean declaration. ]]> </xsd:documentation> </xsd:annotation> </xsd:element> </xsd:choice> <xsd:attribute name="order" type="xsd:int"> <xsd:annotation> <xsd:documentation> <![CDATA[ ViewResolver's registered through this element are encapsulated in an instance of org.springframework.web.servlet.view.ViewResolverComposite and follow the order of registration. This attribute determines the order of the ViewResolverComposite itself relative to any additional ViewResolver's (not registered through this element) present in the Spring configuration By default this property is not set, which means the resolver is ordered at Ordered.LOWEST_PRECEDENCE unless content negotiation is enabled in which case the order (if not set explicitly) is changed to Ordered.HIGHEST_PRECEDENCE. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="tiles-configurer"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure Tiles 3.x by registering a TilesConfigurer bean. This is a shortcut alternative to declaring a TilesConfigurer bean directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="definitions" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="location" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The location of a file containing Tiles definitions (or a Spring resource pattern). If no Tiles definitions are registerd, then "/WEB-INF/tiles.xml" is expected to exists. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="check-refresh" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to check Tiles definition files for a refresh at runtime. Default is "false". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="validate-definitions" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether to validate the Tiles XML definitions. Default is "true". ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="definitions-factory" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The Tiles DefinitionsFactory class to use. Default is Tiles' default. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="preparer-factory" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The Tiles PreparerFactory class to use. Default is Tiles' default. Consider "org.springframework.web.servlet.view.tiles3.SimpleSpringPreparerFactory" or "org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory" (see javadoc). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="freemarker-configurer"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure FreeMarker for view resolution by registering a FreeMarkerConfigurer bean. This is a shortcut alternative to declaring a FreeMarkerConfigurer bean directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="template-loader-path" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="location" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The location of a FreeMarker template loader path (or a Spring resource pattern). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="groovy-configurer"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure the Groovy markup template engine for view resolution by registering a GroovyMarkupConfigurer bean. This is a shortcut alternative to declaring a GroovyMarkupConfigurer bean directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="auto-indent" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether you want the template engine to render indents automatically. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="cache-templates" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ If enabled templates are compiled once for each source (URL or File). It is recommended to keep this flag to true unless you are in development mode and want automatic reloading of templates. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="resource-loader-path" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The Groovy markup template engine resource loader path via a Spring resource location. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="script-template-configurer"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure the script engine for view resolution by registering a ScriptTemplateConfigurer bean. This is a shortcut alternative to declaring a ScriptTemplateConfigurer bean directly. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="script" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="location" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The location of the script to be loaded by the script engine (library or user provided). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="engine-name" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ The script engine name to use by the view. The script engine must implement Invocable. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="render-object" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The object where belong the render function. For example, in order to call Mustache.render(), renderObject should be set to Mustache and renderFunction to render. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="render-function" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the render function name. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="content-type" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the content type to use for the response (text/html by default). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="charset" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Set the charset used to read script and template files (UTF-8 by default). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="resource-loader-path" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ The script engine resource loader path via a Spring resource location. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="shared-engine" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ When set to false, use thread-local ScriptEngine instances instead of one single shared instance. This flag should be set to false for those using non thread-safe script engines with templating libraries not designed for concurrency, like Handlebars or React running on Nashorn for example. In this case, Java 8u60 or greater is required due to this bug: https://bugs.openjdk.java.net/browse/JDK-8076099. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:element name="cors"> <xsd:annotation> <xsd:documentation> <![CDATA[ Configure cross origin requests processing. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="mapping" minOccurs="1" maxOccurs="unbounded"> <xsd:annotation> <xsd:documentation> <![CDATA[ Enable cross origin requests processing on the specified path pattern. By default, all origins, GET HEAD POST methods, all headers and credentials are allowed and max age is set to 30 minutes. ]]> </xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:attribute name="path" type="xsd:string" use="required"> <xsd:annotation> <xsd:documentation> <![CDATA[ A path into the application that should handle CORS requests. Exact path mapping URIs (such as "/admin") are supported as well as Ant-stype path patterns (such as /admin/**). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="allowed-origins" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Comma-separated list of origins to allow, e.g. "https://domain1.com, https://domain2.com". The special value "*" allows all domains (default). Note that CORS checks use values from "Forwarded" (RFC 7239), "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, if present, in order to reflect the client-originated address. Consider using the ForwardedHeaderFilter in order to choose from a central place whether to extract and use such headers, or whether to discard them. See the Spring Framework reference for more on this filter. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="allowed-methods" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Comma-separated list of HTTP methods to allow, e.g. "GET, POST". The special value "*" allows all method. By default GET, HEAD and POST methods are allowed. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="allowed-headers" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Comma-separated list of headers that a pre-flight request can list as allowed for use during an actual request. The special value of "*" allows actual requests to send any header (default). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="exposed-headers" type="xsd:string"> <xsd:annotation> <xsd:documentation> <![CDATA[ Comma-separated list of response headers other than simple headers (i.e. Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma) that an actual response might have and can be exposed. Empty by default. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="allow-credentials" type="xsd:boolean"> <xsd:annotation> <xsd:documentation> <![CDATA[ Whether user credentials are supported (true by default). ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> <xsd:attribute name="max-age" type="xsd:long"> <xsd:annotation> <xsd:documentation> <![CDATA[ How long, in seconds, the response from a pre-flight request can be cached by clients. 1800 seconds (30 minutes) by default. ]]> </xsd:documentation> </xsd:annotation> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
matthewlsawyer / Cache2A declarative cache framework for Java
kylebebak / React Redux QueryA few hooks and functions for declarative data fetching, caching, sharing, automatic updates, and request deduplication
liyupeng / NVPageThe non-volatile memory such as PCM or NV-DIMM is coming. It makes possible that persistent data can be accessed in dram way. However, the current design of linux (page cache, no distinguish between dram and pram) will make trouble: software overhead and resouce usage. So it is necessary to make future OS support persistent ram by using a new foundational mechanism, which is the target of Project NVPage. In this project, we divide page to V-Page and NV-Page which can be recovered during reboot. There are two featrue we provided: 1. Kernal programmer only need declare a page as the NV-Page, and the recover work during reboot is transparent. 2. Kernal programmer only need declare a set of NV-Page increasingly when the set state is legal, the work to maintain consistency during power exception is transparent. The code of project consist of two part: one is modified Gem5 to support pram and the other one is modified linux kernal to support NV-Page.
sanusanth / Java All Basic Program Part 2What is Java? Java is a popular programming language, created in 1995. It is owned by Oracle, and more than 3 billion devices run Java. It is used for: Mobile applications (specially Android apps) Desktop applications Web applications Web servers and application servers Games Database connection And much, much more! Why Use Java? Java works on different platforms (Windows, Mac, Linux, Raspberry Pi, etc.) It is one of the most popular programming language in the world It is easy to learn and simple to use It is open-source and free It is secure, fast and powerful It has a huge community support (tens of millions of developers) Java is an object oriented language which gives a clear structure to programs and allows code to be reused, lowering development costs As Java is close to C++ and C#, it makes it easy for programmers to switch to Java or vice versa Setup for Windows To install Java on Windows: Go to "System Properties" (Can be found on Control Panel > System and Security > System > Advanced System Settings) Click on the "Environment variables" button under the "Advanced" tab Then, select the "Path" variable in System variables and click on the "Edit" button Click on the "New" button and add the path where Java is installed, followed by \bin. By default, Java is installed in C:\Program Files\Java\jdk-11.0.1 (If nothing else was specified when you installed it). In that case, You will have to add a new path with: C:\Program Files\Java\jdk-11.0.1\bin Then, click "OK", and save the settings At last, open Command Prompt (cmd.exe) and type java -version to see if Java is running on your machine Keyword Description abstract A non-access modifier. Used for classes and methods: An abstract class cannot be used to create objects (to access it, it must be inherited from another class). An abstract method can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from) assert For debugging boolean A data type that can only store true and false values break Breaks out of a loop or a switch block byte A data type that can store whole numbers from -128 and 127 case Marks a block of code in switch statements catch Catches exceptions generated by try statements char A data type that is used to store a single character class Defines a class continue Continues to the next iteration of a loop const Defines a constant. Not in use - use final instead default Specifies the default block of code in a switch statement do Used together with while to create a do-while loop double A data type that can store whole numbers from 1.7e−308 to 1.7e+308 else Used in conditional statements enum Declares an enumerated (unchangeable) type exports Exports a package with a module. New in Java 9 extends Extends a class (indicates that a class is inherited from another class) final A non-access modifier used for classes, attributes and methods, which makes them non-changeable (impossible to inherit or override) finally Used with exceptions, a block of code that will be executed no matter if there is an exception or not float A data type that can store whole numbers from 3.4e−038 to 3.4e+038 for Create a for loop goto Not in use, and has no function if Makes a conditional statement implements Implements an interface import Used to import a package, class or interface instanceof Checks whether an object is an instance of a specific class or an interface int A data type that can store whole numbers from -2147483648 to 2147483647 interface Used to declare a special type of class that only contains abstract methods long A data type that can store whole numbers from -9223372036854775808 to 9223372036854775808 module Declares a module. New in Java 9 native Specifies that a method is not implemented in the same Java source file (but in another language) new Creates new objects package Declares a package private An access modifier used for attributes, methods and constructors, making them only accessible within the declared class protected An access modifier used for attributes, methods and constructors, making them accessible in the same package and subclasses public An access modifier used for classes, attributes, methods and constructors, making them accessible by any other class requires Specifies required libraries inside a module. New in Java 9 return Finished the execution of a method, and can be used to return a value from a method short A data type that can store whole numbers from -32768 to 32767 static A non-access modifier used for methods and attributes. Static methods/attributes can be accessed without creating an object of a class strictfp Restrict the precision and rounding of floating point calculations super Refers to superclass (parent) objects switch Selects one of many code blocks to be executed synchronized A non-access modifier, which specifies that methods can only be accessed by one thread at a time this Refers to the current object in a method or constructor throw Creates a custom error throws Indicates what exceptions may be thrown by a method transient A non-accesss modifier, which specifies that an attribute is not part of an object's persistent state try Creates a try...catch statement var Declares a variable. New in Java 10 void Specifies that a method should not have a return value volatile Indicates that an attribute is not cached thread-locally, and is always read from the "main memory" while Creates a while loop Method Description Return Type charAt() Returns the character at the specified index (position) char codePointAt() Returns the Unicode of the character at the specified index int codePointBefore() Returns the Unicode of the character before the specified index int codePointCount() Returns the Unicode in the specified text range of this String int compareTo() Compares two strings lexicographically int compareToIgnoreCase() Compares two strings lexicographically, ignoring case differences int concat() Appends a string to the end of another string String contains() Checks whether a string contains a sequence of characters boolean contentEquals() Checks whether a string contains the exact same sequence of characters of the specified CharSequence or StringBuffer boolean copyValueOf() Returns a String that represents the characters of the character array String endsWith() Checks whether a string ends with the specified character(s) boolean equals() Compares two strings. Returns true if the strings are equal, and false if not boolean equalsIgnoreCase() Compares two strings, ignoring case considerations boolean format() Returns a formatted string using the specified locale, format string, and arguments String getBytes() Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array byte[] getChars() Copies characters from a string to an array of chars void hashCode() Returns the hash code of a string int indexOf() Returns the position of the first found occurrence of specified characters in a string int intern() Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index String isEmpty() Checks whether a string is empty or not boolean lastIndexOf() Returns the position of the last found occurrence of specified characters in a string int length() Returns the length of a specified string int matches() Searches a string for a match against a regular expression, and returns the matches boolean offsetByCodePoints() Returns the index within this String that is offset from the given index by codePointOffset code points int regionMatches() Tests if two string regions are equal boolean replace() Searches a string for a specified value, and returns a new string where the specified values are replaced String replaceFirst() Replaces the first occurrence of a substring that matches the given regular expression with the given replacement String replaceAll() Replaces each substring of this string that matches the given regular expression with the given replacement String split() Splits a string into an array of substrings String[] startsWith() Checks whether a string starts with specified characters boolean subSequence() Returns a new character sequence that is a subsequence of this sequence CharSequence substring() Extracts the characters from a string, beginning at a specified start position, and through the specified number of character String toCharArray() Converts this string to a new character array char[] toLowerCase() Converts a string to lower case letters String toString() Returns the value of a String object String toUpperCase() Converts a string to upper case letters String trim() Removes whitespace from both ends of a string String valueOf() Returns the primitive value of a String object String Method Description Return Type abs(x) Returns the absolute value of x double|float|int|long acos(x) Returns the arccosine of x, in radians double asin(x) Returns the arcsine of x, in radians double atan(x) Returns the arctangent of x as a numeric value between -PI/2 and PI/2 radians double atan2(y,x) Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta). double cbrt(x) Returns the cube root of x double ceil(x) Returns the value of x rounded up to its nearest integer double copySign(x, y) Returns the first floating point x with the sign of the second floating point y double cos(x) Returns the cosine of x (x is in radians) double cosh(x) Returns the hyperbolic cosine of a double value double exp(x) Returns the value of Ex double expm1(x) Returns ex -1 double floor(x) Returns the value of x rounded down to its nearest integer double getExponent(x) Returns the unbiased exponent used in x int hypot(x, y) Returns sqrt(x2 +y2) without intermediate overflow or underflow double IEEEremainder(x, y) Computes the remainder operation on x and y as prescribed by the IEEE 754 standard double log(x) Returns the natural logarithm (base E) of x double log10(x) Returns the base 10 logarithm of x double log1p(x) Returns the natural logarithm (base E) of the sum of x and 1 double max(x, y) Returns the number with the highest value double|float|int|long min(x, y) Returns the number with the lowest value double|float|int|long nextAfter(x, y) Returns the floating point number adjacent to x in the direction of y double|float nextUp(x) Returns the floating point value adjacent to x in the direction of positive infinity double|float pow(x, y) Returns the value of x to the power of y double random() Returns a random number between 0 and 1 double round(x) Returns the value of x rounded to its nearest integer int rint() Returns the double value that is closest to x and equal to a mathematical integer double signum(x) Returns the sign of x double sin(x) Returns the sine of x (x is in radians) double sinh(x) Returns the hyperbolic sine of a double value double sqrt(x) Returns the square root of x double tan(x) Returns the tangent of an angle double tanh(x) Returns the hyperbolic tangent of a double value double toDegrees(x) Converts an angle measured in radians to an approx. equivalent angle measured in degrees double toRadians(x) Converts an angle measured in degrees to an approx. angle measured in radians double ulp(x) Returns the size of the unit of least precision (ulp) of x double|float